Example #1
0
class MonoBlocks(ControlSurface):


	_rgb = 0
	_color_type = 'Push'
	_timer = 0
	_touched = 0
	flash_status = False
	_model_name = 'MonoBlocks'
	_host_name = 'MonoBlocks'
	_version_check = 'b996'
	monomodular = None
	device_provider_class = ModDeviceProvider

	def __init__(self, *a, **k):
		super(MonoBlocks, self).__init__(*a, **k)
		self.log_message = logger.info
		self._skin = Skin(MonoBlocksColors)
		with self.component_guard():
			self._setup_monobridge()
			self._setup_controls()
			#self._setup_device()
			self._setup_mod()
			#self._setup_modes()
			self._setup_modswitcher()
		self._on_device_changed.subject = self._device_provider
		self.schedule_message(1, self._open_log)


	def _open_log(self):
		#self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._model_name) + " " + str(self._version_check) + " log opened =>>>>>>>>>>>>>>>>>>>")
		self.show_message(str(self._model_name) + ' Control Surface Loaded')


	def _close_log(self):
		#self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._model_name) + " " + str(self._version_check) + " log closed =>>>>>>>>>>>>>>>>>>>")
		pass


	def _setup_controls(self):
		is_momentary = True
		optimized = True
		resource = PrioritizedResource
		#self._pads_raw = [ ButtonElement(True, MIDI_NOTE_TYPE, 0, identifier, name=u'Pad_{}'.format(identifier), skin=skin) for identifier in xrange(100) ]
		self._pad = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = BLOCKS_PADS[index], name = 'Pad_' + str(index), script = self, monobridge = self._monobridge, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource) for index in range(64)]
		for button in self._pad:
			button.set_color_map(tuple(range(128)))
		self._matrix = ButtonMatrixElement(name = 'Matrix', rows = [self._pad[(index*8):(index*8)+8] for index in range(8)])


	#def _setup_device(self):
	#	self._device_selection_follows_track_selection = True
	#	self._device = DeviceComponent(name = 'Device_Component', device_bank_registry = DeviceBankRegistry(), device_provider = self._device_provider)
	#	self._device.set_enabled(True)


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


	def _setup_mod(self):

		def get_monomodular(host):
				if isinstance(__builtins__, dict):
					if not 'monomodular' in __builtins__.keys() or not isinstance(__builtins__['monomodular'], ModRouter):
						__builtins__['monomodular'] = ModRouter(song = self.song, register_component = self._register_component)
				else:
					if not hasattr(__builtins__, 'monomodular') or not isinstance(__builtins__['monomodular'], ModRouter):
						setattr(__builtins__, 'monomodular', ModRouter(song = self.song, register_component = self._register_component))
				monomodular = __builtins__['monomodular']
				if not monomodular.has_host():
					monomodular.set_host(host)
				return monomodular


		self.monomodular = get_monomodular(self)
		self.monomodular.name = 'monomodular_switcher'
		with inject(register_component = const(self._register_component), song = const(self.song)).everywhere():
			self.modhandler = MonoBlocksModHandler(self) ## song = self.song, register_component = self._register_component)
		self.modhandler.name = 'ModHandler'
		self.modhandler.layer = Layer( priority = 6, grid = self._matrix)
		self.modhandler.alt_shift_layer = AddLayerMode( self.modhandler, Layer())
		#																	Shift_button = self.elements.shift_button,
		#																	Alt_button = self.elements.select_button))
		self.modhandler.legacy_shift_layer = AddLayerMode( self.modhandler, Layer(priority = 7,
																			device_selector_matrix = self._matrix.submatrix[:, :1],
																			channel_buttons = self._matrix.submatrix[:, 1:2],
																			nav_matrix = self._matrix.submatrix[4:8, 2:6],
																			))
		self.modhandler.shift_layer = AddLayerMode( self.modhandler, Layer( priority = 7,
																			device_selector_matrix = self._matrix.submatrix[:, :1],
																			))
																			#lock_button = self.elements.master_select_button,
																			#))
		self.modhandler.alt_layer = AddLayerMode( self.modhandler, Layer( priority = 7,
																			))
																			#key_buttons = self.elements.select_buttons))
																			#key_buttons = self.elements.track_state_buttons))
		self._device_provider.restart_mod()


	def _setup_modswitcher(self):
		self._modswitcher = ModesComponent(name = 'ModSwitcher')
		self._modswitcher.add_mode('mod', [self.modhandler])
		self._modswitcher.selected_mode = 'mod'
		self._modswitcher.set_enabled(True)


	def flash(self):
		if(self.flash_status > 0):
			for control in self.controls:
				if isinstance(control, MonoButtonElement):
					control.flash(self._timer)


	def update_display(self):
		super(ControlSurface, self).update_display()
		self._timer = (self._timer + 1) % 256
		self.flash()


	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)


	@listens('device')
	def _on_device_changed(self):
		#self.schedule_message(1, self._update_modswitcher)
		debug('base on_device_changed')
		#self._update_modswitcher()


	def _on_selected_track_changed(self):
		super(MonoBlocks, self)._on_selected_track_changed()
		if not len(self.song.view.selected_track.devices):
			self._update_modswitcher()
		#self.schedule_message(1, self._update_modswitcher)


	def disconnect(self):
		super(MonoBlocks, self).disconnect()
		self._close_log()


	def restart_monomodular(self):
		#self.log_message('restart monomodular')
		self.modhandler.disconnect()
		with self.component_guard():
			self._setup_mod()


	def process_midi_bytes(self, midi_bytes, midi_processor):
		u"""
		Finds the right recipient for the MIDI message and translates it into the
		expected format. The result is forwarded to the midi_processor.
		"""
		if midi.is_sysex(midi_bytes):
			result = self.get_registry_entry_for_sysex_midi_message(midi_bytes)
			if result is not None:
				identifier, recipient = result
				midi_processor(recipient, midi_bytes[len(identifier):-1])
			#elif self.received_midi_listener_count() == 0:
			#	logger.warning(u'Got unknown sysex message: ' + midi.pretty_print_bytes(midi_bytes))
		else:
			recipient = self.get_recipient_for_nonsysex_midi_message(midi_bytes)
			if recipient is not None:
				midi_processor(recipient, midi.extract_value(midi_bytes))
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)
Example #3
0
class Codec(LividControlSurface):


	_sysex_id = 4
	_model_name = 'Code'
	_host_name = 'Codec'
	_version_check = 'b996'
	monomodular = None

	def __init__(self, c_instance, *a, **k):
		self.log_message = logger.warning
		super(Codec, self).__init__(c_instance, *a, **k)
		self._locked = False
		self._shift_button = None
		self._device_selection_follows_track_selection=FOLLOW
		self._leds_last = 0
		self._shift_latching = LatchingShiftedBehaviour if SHIFT_LATCHING else ShiftedBehaviour
		self._skin = Skin(CodecColors)
		with self.component_guard():
			self._define_sysex()
			self._setup_controls()
			self._setup_background()
			self._setup_mixer_controls()
			self._setup_device_navigator()
			self._setup_device_controls()
			self._setup_special_device_control() 
			self._setup_device_chooser()
			self._setup_device_selector()
			self._setup_send_reset()
			self._setup_default_buttons()
			self._setup_shift_modes()
			self._setup_mod()
			self._setup_modswitcher()
			self._setup_modes() 
			self._setup_m4l_interface()
		self._background.set_enabled(True)
	

	def _initialize_hardware(self):
		super(Codec, self)._initialize_hardware()
	

	def _initialize_script(self):
		super(Codec, self)._initialize_script()
		self._on_device_changed.subject = self._device_provider
		self._main_modes.set_enabled(True)
		self._main_modes.selected_mode = 'mix'
	

	def _define_sysex(self):
		self.fast_encoder_sysex = SendLividSysexMode(livid_settings = self._livid_settings, call = 'set_encoder_speed', message = FAST_ENCODER_MSG)
		self.normal_encoder_sysex = SendLividSysexMode(livid_settings = self._livid_settings, call = 'set_encoder_speed', message = NORMAL_ENCODER_MSG)
		self.slow_encoder_sysex = SendLividSysexMode(livid_settings = self._livid_settings, call = 'set_encoder_speed', message = SLOW_ENCODER_MSG)
	

	def _setup_controls(self):
		is_momentary = True
		optimized = False
		resource = PrioritizedResource
		self._livid = DoublePressElement(MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = LIVID, name = 'Livid_Button', script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge))
		self._dial = [[CodecEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CODE_DIALS[row][column], name = 'Dial_' + str(column) + '_' +	str(row), num = (column + (row*8)), script = self, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge)	for row in range(4)] for column in range(8)]
		self._button = [[MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CODE_BUTTONS[row][column], name = 'Button_' + str(column) + '_' + str(row), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for row in range(4)] for column in range(8)]
		self._column_button = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CODE_COLUMN_BUTTONS[index], name = 'Column_Button_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(8)]		
		self._row_button = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CODE_ROW_BUTTONS[index], name = 'Row_Button_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(4)]	
		self._code_keys = ButtonMatrixElement(name = 'Code_Keys', rows = [self._column_button])
		self._code_buttons = ButtonMatrixElement(name = 'Code_Buttons', rows = [self._row_button])
		self._encoder_matrix = ButtonMatrixElement(name = 'Encoder_Matrix', rows = [[self._dial[column][row] for column in range(8)] for row in range(4)])
		self._button_matrix = ButtonMatrixElement(name = 'Button_Matrix', rows = [[self._button[column][row] for column in range(8)] for row in range(4)])
	

	def _setup_background(self):
		self._background = BackgroundComponent()
		self._background.layer = Layer(priority = 3, matrix = self._button_matrix, encoders = self._encoder_matrix, livid = self._livid, buttons = self._code_buttons, keys = self._code_keys)
		self._background.set_enabled(False)
	

	def _setup_transport_control(self):
		self._transport = TransportComponent() 
		self._transport.name = 'Transport'
		self._transport.set_enabled(False)
	

	def _setup_mixer_controls(self):
		self._session_ring = SessionRingComponent(name = 'Session_Ring', num_tracks = 8, num_scenes = 0)
		self._session_navigation = SessionNavigationComponent(name = 'Session_Navigation', session_ring = self._session_ring)
		self._session_navigation.layer = Layer(priority = 4, left_button = self._button[6][0], right_button = self._button[7][0])
		self._session_navigation.set_enabled(False)
		#self._session = SessionComponent(name = 'Session', session_ring = self._session_ring)
		self._mixer = CodecMixerComponent(num_returns = 4, name = 'Mixer', tracks_provider = self._session_ring, invert_mute_feedback = True, auto_name = True)
		self._mixer._mix_layer = AddLayerMode(self._mixer, Layer(priority = 4, volume_controls = self._encoder_matrix.submatrix[:8,3],
									pan_controls = self._encoder_matrix.submatrix[:8,2],
									send_controls = self._encoder_matrix.submatrix[:8, :2],
									))
		self._mixer._solo_mute_layer = AddLayerMode(self._mixer, Layer(priority = 4, solo_buttons = self._button_matrix.submatrix[:8,2],
									mute_buttons = self._button_matrix.submatrix[:8,3],
									))
		self._mixer._select_layer = AddLayerMode(self._mixer, Layer(priority = 4, track_select_buttons = self._code_keys))
		self._mixer._sends_layer = AddLayerMode(self._mixer, Layer(priority = 4, send_controls = self._encoder_matrix.submatrix[:, :]))
		self._mixer.set_enabled(False)
	

	def _setup_device_navigator(self):
		self._device_navigator = DeviceNavigator(self._device_provider, self._mixer, self)
		self._device_navigator._dev1_layer = AddLayerMode(self._device_navigator, Layer(priority = 4, prev_button = self._button[4][0], next_button = self._button[5][0], prev_chain_button = self._button[6][0], next_chain_button = self._button[7][0]))
		self._device_navigator._dev2_layer = AddLayerMode(self._device_navigator, Layer(priority = 4, prev_button = self._button[4][1], next_button = self._button[5][1], prev_chain_button = self._button[6][1], next_chain_button = self._button[7][1]))
		self._device_navigator._dev3_layer = AddLayerMode(self._device_navigator, Layer(priority = 4, prev_button = self._button[4][2], next_button = self._button[5][2], prev_chain_button = self._button[6][2], next_chain_button = self._button[7][2]))
		self._device_navigator._dev4_layer = AddLayerMode(self._device_navigator, Layer(priority = 4, prev_button = self._button[4][3], next_button = self._button[5][3], prev_chain_button = self._button[6][3], next_chain_button = self._button[7][3]))
		self._device_navigator.set_enabled(False)
	

	def _setup_device_controls(self):
		self._device = [None for index in range(4)]
		for index in range(4):
			self._device[index] = CodecDeviceComponent(self, index+1, device_bank_registry = DeviceBankRegistry())
			self._device[index].name = 'CodecDevice_Component_' + str(index+1)
			self._device[index].layer = Layer(priority = 4, parameter_controls = self._encoder_matrix.submatrix[:, index],
												on_off_button = self._button[1][index],
												bank_prev_button = self._button[2][index],
												bank_next_button = self._button[3][index],
												)
			self._device[index]._nav_layer = AddLayerMode(self._device[index], Layer(priority = 4, nav_prev_button = self._button[6][index],
																					nav_next_button = self._button[7][index],))
			self._device[index].set_enabled(False)
	

	def _setup_special_device_control(self):
		self._special_device = SpecialCodecDeviceComponent(self, device_bank_registry = DeviceBankRegistry(), device_provider = self._device_provider)
		self._special_device.name = 'SpecialCodecDeviceComponent'
		self._is_active_device = True
		self._special_device.layer = Layer(priority = 4, parameter_controls = self._encoder_matrix.submatrix[:,:],
											on_off_button = self._button[1][0],
											bank_prev_button = self._button[4][0],
											bank_next_button = self._button[5][0],
											)
		self._special_device.set_enabled(False)
	

	def _setup_device_chooser(self):
		self._selected_device = self._device[0]
		self._last_selected_device = self._device[0]

		self._selected_device_modes = ModesComponent()
		self._selected_device_modes.add_mode('disabled', [None])
		self._selected_device_modes.add_mode('device_0', [self._device_navigator._dev1_layer], behaviour = DefaultedBehaviour())
		self._selected_device_modes.add_mode('device_1', [self._device_navigator._dev2_layer], behaviour = DefaultedBehaviour())
		self._selected_device_modes.add_mode('device_2', [self._device_navigator._dev3_layer], behaviour = DefaultedBehaviour())
		self._selected_device_modes.add_mode('device_3', [self._device_navigator._dev4_layer], behaviour = DefaultedBehaviour())
		self._selected_device_modes.layer = Layer(priority = 4, device_0_button = self._button[0][0], device_1_button = self._button[0][1], device_2_button = self._button[0][2], device_3_button = self._button[0][3])
		self._selected_device_modes.selected_mode = 'device_0'
		self._selected_device_modes.set_enabled(False)
		self._on_device_selector_mode_changed.subject = self._selected_device_modes
	

	def _setup_device_selector(self):
		self._device_selector = DeviceSelectorComponent(self)
		self._device_selector.name = 'Device_Selector'
		self._device_selector.layer = Layer(priority = 4, matrix = self._code_keys)
		self._device_selector.set_enabled(False)
	

	def _setup_send_reset(self):
		self._send_reset = CodecResetSendsComponent(self)
		self._send_reset.set_enabled(False)
		#self._send_reset.set_buttons(self._button)
	

	def _setup_default_buttons(self):
		self._value_default = ParameterDefaultComponent(script = self, dials = self._dial)
		self._value_default.layer = Layer(priority = 3, matrix = self._button_matrix)
		self._value_default.set_enabled(False)
	

	def _setup_shift_modes(self):
		self._main_shift_modes = ModesComponent(name = 'MainShiftModes')
		self._main_shift_modes.add_mode('disabled', [self.normal_encoder_sysex], cycle_mode_button_color = 'DefaultButton.Off')
		self._main_shift_modes.add_mode('enabled', [self.slow_encoder_sysex], cycle_mode_button_color = 'DefaultButton.On')  #, self._value_default
		self._main_shift_modes.layer = Layer(priority = 4, cycle_mode_button = self._livid)
		self._main_shift_modes.set_enabled(False)
		self._main_shift_modes.selected_mode = 'disabled'

		self._mod_shift_modes = ModesComponent(name = 'ModShiftModes')
		self._mod_shift_modes.layer = Layer(priority = 4, cycle_mode_button = self._livid)
		self._mod_shift_modes.set_enabled(False)
	

	def _setup_mod(self):
		self.monomodular = get_monomodular(self)
		self.monomodular.name = 'monomodular_switcher'
		self.modhandler = CodecModHandler(script = self, device_provider = self._device_provider)
		self.modhandler.name = 'ModHandler'
		self.modhandler.layer = Layer(priority = 4, code_grid = self._button_matrix.submatrix[:,:], code_encoder_grid = self._encoder_matrix.submatrix[:,:])
		self.modhandler.set_enabled(False)
		self.modhandler.code_buttons_layer = AddLayerMode(self.modhandler, Layer(priority = 5, code_buttons = self._code_buttons))
		self.modhandler.keys_layer = AddLayerMode(self.modhandler, Layer(priority = 5, key_buttons = self._code_keys))
		self.modhandler.code_keys_layer = AddLayerMode(self.modhandler, Layer(priority = 5, code_keys = self._code_buttons))
		self.modhandler.alt_layer = AddLayerMode(self.modhandler, Layer(priority = 4, lock_button = self._livid))
	

	def _setup_modswitcher(self):
		self._modswitcher = ModesComponent(name = 'ModSwitcher')
		self._modswitcher.add_mode('mod', [self.modhandler, self._mod_shift_modes])
		self._modswitcher.add_mode('special_device', [self._special_device, self._mixer, self._mixer._select_layer, self._main_shift_modes])
		self._modswitcher.selected_mode = 'special_device'
		self._modswitcher.set_enabled(False)

		self._mod_shift_modes.add_mode('disabled', [self.modhandler.keys_layer], cycle_mode_button_color = 'Mod.ShiftOff')
		self._mod_shift_modes.add_mode('enabled', [self.modhandler.code_keys_layer, self.modhandler.code_buttons_layer, tuple([self._send_mod_shift, self._release_mod_shift])], cycle_mode_button_color = 'Mod.ShiftOn')
		self._mod_shift_modes.selected_mode = 'disabled'
	

	def _setup_modes(self):
		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('disabled', [])
		self._main_modes.add_mode('mix_shifted', [self._mixer, self._mixer._mix_layer, self._mixer._solo_mute_layer, self._device_selector, self._background], groups = ['shifted'], behaviour = self._shift_latching(color = 'Mode.Main'))
		self._main_modes.add_mode('mix', [self._mixer, self._mixer._mix_layer, self._mixer._select_layer, self._mixer._solo_mute_layer, self._session_navigation, self._background, self._main_shift_modes], behaviour = self._shift_latching(color = 'Mode.Main'))
		self._main_modes.add_mode('sends_shifted', [self._mixer, self._mixer._sends_layer, self._mixer._select_layer, self._device_selector, self._background], groups = ['shifted'], behaviour = self._shift_latching(color = 'Mode.Main'))
		self._main_modes.add_mode('sends', [self._mixer, self._mixer._sends_layer, self._mixer._select_layer, self._background, self._main_shift_modes], behaviour = self._shift_latching(color = 'Mode.Main'))
		self._main_modes.add_mode('device_shifted', [self._selected_device_modes, self._device_selector, self._device[0], self._device[1], self._device[2], self._device[3], self._device_selector, self._background], groups = ['shifted'], behaviour = self._shift_latching(color = 'Mode.Main'))
		self._main_modes.add_mode('device', [self._mixer, self._mixer._select_layer, self._selected_device_modes, self._device[0], self._device[1], self._device[2], self._device[3], self._background, self._mixer._select_layer, self._main_shift_modes], behaviour = self._shift_latching(color = 'Mode.Main'))
		self._main_modes.add_mode('special_device_shifted', [self._modswitcher, self._device_selector, self._background], groups = ['shifted'], behaviour = self._shift_latching(color = 'Mode.Main'))
		self._main_modes.add_mode('special_device', [self._modswitcher, self._background], behaviour = self._shift_latching(color = 'Mode.Main'))
		#self._main_modes.add_mode('select', [self.normal_encoder_sysex], behaviour = DelayedExcludingMomentaryBehaviour(excluded_groups = ['shifted']))
		self._main_modes.layer = Layer(priority = 4,
										mix_button = self._row_button[0],
										sends_button = self._row_button[1],
										device_button = self._row_button[2],
										special_device_button = self._row_button[3],
										)
		self._main_modes.selected_mode = 'disabled'
		self._main_modes.set_enabled(False)
	

	def _setup_m4l_interface(self):
		self._m4l_interface = M4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard)
		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
	

	@listens('selected_mode')
	def _on_device_selector_mode_changed(self, mode):
		if mode == 'disabled':
			for device in self._device:
				device.set_dynamic_device_provider(None)
		elif mode in DEVICE_COMPONENTS:
			active_device = self._device[DEVICE_COMPONENTS.index(self._selected_device_modes.selected_mode)]
			for device in self._device:
				if device is active_device:
					device.set_dynamic_device_provider(self._device_provider)
				else:
					device.set_dynamic_device_provider(None)
			if active_device.find_track(active_device._get_device()) == self.song.view.selected_track:
				active_device.display_device()
	

	@listens('device')
	def _on_device_changed(self):
		self._on_device_name_changed.subject = self._device_provider.device
		self.schedule_message(1, self._update_modswitcher)
	

	@listens('name')
	def _on_device_name_changed(self):
		for device in self._device:
			device.scan_all()
	

	def _on_selected_track_changed(self):
		super(Codec, self)._on_selected_track_changed()
		#self.schedule_message(1, self._update_modswitcher)
		if not len(self.song.view.selected_track.devices):
			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 = 'special_device'
	

	"""general functionality"""
	def disconnect(self):
		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Codec log closed >>>>>>>>>>>>>>>>>>>>>>>>>')
		super(Codec, self).disconnect()
	

	def update_display(self):
		super(Codec, self).update_display()
		self.modhandler.send_ring_leds()
	

	def restart_monomodular(self):
		#self.log_message('restart monomodular')
		self.modhandler.disconnect()
		with self.component_guard():
			self._setup_mod()
	

	def _send_mod_shift(self):
		self.modhandler._shift_value(1)
	

	def _release_mod_shift(self):
		self.modhandler._shift_value(0)
Example #4
0
class Twister(LividControlSurface):
    __module__ = __name__
    __doc__ = " Monomodular controller script for Livid CNTRLR "

    _sysex_id = 8
    _model_name = 'Twister'
    _host_name = 'Twister'
    _version_check = 'b996'
    monomodular = None

    device_provider_class = ModDeviceProvider

    def __init__(self, *a, **k):
        super(Twister, self).__init__(*a, **k)
        self._skin = Skin(TwisterColors)
        self._device_selection_follows_track_selection = True
        with self.component_guard():
            self._setup_monobridge()
            self._setup_controls()
            #self._define_sysex()
            self._setup_background()
            self._setup_m4l_interface()
            self._setup_mod()
            self._setup_device_control()
            self._setup_modes()
        self._on_device_changed.subject = self.song
        self._on_selected_track_changed.subject = self.song.view

    def _initialize_script(self):
        super(Twister, self)._initialize_script()
        self._connected = True

    def _setup_controls(self):
        is_momentary = True
        optimized = True
        resource = PrioritizedResource
        self._encoder = [
            CodecEncoderElement(msg_type=MIDI_CC_TYPE,
                                channel=CHANNEL,
                                identifier=TWISTER_DIALS[index],
                                name='Encoder_' + str(index),
                                num=TWISTER_DIALS[index],
                                script=self,
                                optimized_send_midi=optimized,
                                resource_type=resource,
                                monobridge=self._monobridge)
            for index in range(16)
        ]
        self._encoder_button = [
            TwisterButtonElement(is_momentary=is_momentary,
                                 msg_type=MIDI_CC_TYPE,
                                 channel=1,
                                 identifier=TWISTER_DIAL_BUTTONS[index],
                                 name='Encoder_Button_' + str(index),
                                 script=self,
                                 skin=self._skin,
                                 color_map=COLOR_MAP,
                                 optimized_send_midi=optimized,
                                 resource_type=resource,
                                 monobridge=self._monobridge)
            for index in range(16)
        ]

        self._dial_matrix = ButtonMatrixElement(
            name='Dial_Matrix',
            rows=[
                self._encoder[index * 4:(index * 4) + 4] for index in range(4)
            ])
        self._dial_button_matrix = ButtonMatrixElement(
            name='Dial_Button_Matrix',
            rows=[
                self._encoder_button[index * 4:(index * 4) + 4]
                for index in range(4)
            ])

    def _setup_background(self):
        self._background = BackgroundComponent(name='Background')
        self._background.layer = Layer(
            priority=3,
            dials=self._dial_matrix,
            dial_buttons=self._dial_button_matrix.submatrix[:, :])
        self._background.set_enabled(True)

    def _setup_m4l_interface(self):
        self._m4l_interface = M4LInterfaceComponent(
            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 _define_sysex(self):
        pass

    def _check_connection(self):
        self._connected = True
        self._initialize_hardware()
        self._initialize_script()

    def _setup_mixer_control(self):
        self._mixer_session_ring = SessionRingComponent(num_tracks=4,
                                                        num_scenes=4)
        self._mixer = MonoMixerComponent(
            name='Mixer',
            tracks_provider=self._mixer_session_ring,
            track_assigner=simple_track_assigner,
            invert_mute_feedback=True,
            auto_name=True,
            enable_skinning=True)

        self._mixer.layer = Layer(
            priority=4,
            solo_buttons=self._dial_button_matrix.submatrix[:, 0],
            stop_clip_buttons=self._dial_button_matrix.submatrix[:, 1],
            track_select_buttons=self._dial_button_matrix.submatrix[:, 2])
        self._mixer.set_enabled(True)

    def _setup_device_control(self):
        self._device = SpecialDeviceComponent(
            name='Device_Component',
            device_provider=self._device_provider,
            device_bank_registry=DeviceBankRegistry(),
            script=self)
        self._device.layer = Layer(
            priority=4,
            parameter_controls=self._dial_matrix.submatrix[:, :],
        )
        self._device.bank_layer = AddLayerMode(
            self._device,
            Layer(priority=4,
                  bank_prev_button=self._encoder_button[12],
                  bank_next_button=self._encoder_button[13]))
        self._device.set_enabled(False)

    def _setup_mod(self):
        self.monomodular = get_monomodular(self)
        self.monomodular.name = 'monomodular_switcher'
        self.modhandler = TwisterModHandler(
            self, device_provider=self._device_provider)
        self.modhandler.name = 'ModHandler'
        self.modhandler.layer = Layer(
            priority=8,
            twister_encoder_button_grid=self._dial_button_matrix.
            submatrix[:, :],
        )
        #twister_encoder_grid = self._dial_matrix.submatrix[:,:],)
        self.modhandler.set_enabled(False)

    def _setup_modes(self):
        self._modswitcher = ModesComponent(name='ModSwitcher')
        self._modswitcher.add_mode('mod', [self.modhandler, self._device])
        self._modswitcher.add_mode('device',
                                   [self._device, self._device.bank_layer])
        self._modswitcher.selected_mode = 'device'
        self._modswitcher.set_enabled(True)

    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 = 'device'

    @listens('appointed_device')
    def _on_device_changed(self):
        debug('appointed device changed, script')
        self._update_modswitcher()

    @listens('selected_track')
    def _on_selected_track_changed(self):
        debug('_on_selected_track_changed')
        #super(Cntrlr, self)._on_selected_track_changed()
        #self._drum_group_finder.device_parent = self.song.veiw.selected_track
        if not len(self.song.view.selected_track.devices):
            self._update_modswitcher()

    def restart_monomodular(self):
        #debug('restart monomodular')
        self.modhandler.disconnect()
        with self.component_guard():
            self._setup_mod()
class Push(PushBase):
    """
    Push controller script.
    
    Disclaimer: Any use of the Push control surface code (the "Code")
    or parts thereof for commercial purposes or in a commercial context
    is not allowed. Though we do not grant a license for non-commercial
    use of the Code, you may use it in this regard but should be aware that
    (1) we reserve the right to deny the future use any time and
    (2) you need to check whether the use is allowed under the national law
    applicable to your use.
    """
    input_target_name_for_auto_arm = 'Push Input'

    def __init__(self, *a, **k):
        super(Push, self).__init__(*a, **k)
        with self.component_guard():
            self.initialize()
        logger.info('Push script loaded')
        self._send_midi(sysex.WELCOME_MESSAGE)

    def disconnect(self):
        super(Push, self).disconnect()
        logger.info('Push script unloaded')
        self._send_midi(sysex.GOOD_BYE_MESSAGE)

    def port_settings_changed(self):
        super(Push, self).port_settings_changed()
        self._start_handshake_task.restart()

    def on_select_clip_slot(self, clip_slot):
        self._selector.on_select_clip(clip_slot)

    def on_select_scene(self, scene):
        self._selector.on_select_scene(scene)

    def on_select_track(self, track):
        self._selector.on_select_track(track)

    def _create_components(self):
        self._init_handshake()
        self._init_selector()
        super(Push, self)._create_components()
        self._init_browser()
        self._init_track_modes()

    def _create_settings(self):
        settings = create_settings(preferences=self.preferences)
        self.__on_pad_curve.subject = settings['curve']
        self.__on_pad_threshold.subject = settings['threshold']
        self.__on_aftertouch_threshold.subject = settings['aftertouch_threshold']
        return settings

    def _init_settings(self):
        super(Push, self)._init_settings()
        self._init_global_pad_parameters()
        self._update_pad_params()

    def _init_selector(self):
        self._selector = SelectComponent(name='Selector', is_root=True)
        self._selector.layer = Layer(select_button='select_button')
        self._selector.selection_display_layer = Layer(display_line='display_line3', priority=consts.DIALOG_PRIORITY)

    def _init_handshake(self):
        dongle_message, dongle = make_dongle_message(sysex.DONGLE_ENQUIRY_PREFIX)
        identity_control = create_sysex_element(sysex.IDENTITY_PREFIX, sysex.IDENTITY_ENQUIRY)
        dongle_control = create_sysex_element(sysex.DONGLE_PREFIX, dongle_message)
        presentation_control = create_sysex_element(sysex.DONGLE_PREFIX, sysex.make_presentation_message(self.application()))
        self._handshake = HandshakeComponent(identity_control=identity_control, dongle_control=dongle_control, presentation_control=presentation_control, dongle=dongle, is_root=True)
        self._on_handshake_success.subject = self._handshake
        self._on_handshake_failure.subject = self._handshake
        self._start_handshake_task = self._tasks.add(task.sequence(task.wait(HANDSHAKE_DELAY), task.run(self._start_handshake)))
        self._start_handshake_task.kill()

    def _init_user(self):
        super(Push, self)._init_user()
        self._on_push_hardware_mode_changed.subject = self._user
        self._update_pad_params()

    def _with_firmware_version(self, major_version, minor_version, control_element):
        return MinimumFirmwareVersionElement(major_version, minor_version, control_element, self._handshake)

    def _start_handshake(self):
        self._start_handshake_task.kill()
        self.elements.playhead_element.proxied_object = self._c_instance.playhead
        self._note_repeat.set_note_repeat(self._c_instance.note_repeat)
        self._accent_component.set_full_velocity(self._c_instance.full_velocity)
        for control in self.controls:
            receive_value_backup = getattr(control, '_receive_value_backup', nop)
            if receive_value_backup != nop:
                control.receive_value = receive_value_backup
            send_midi_backup = getattr(control, '_send_midi_backup', nop)
            if send_midi_backup != nop:
                control.send_midi = send_midi_backup

        self._handshake._start_handshake()
        self.update()

    @listens('success')
    def _on_handshake_success(self):
        logger.info('Handshake succeded with firmware version %.2f!' % self._handshake.firmware_version)
        self.update()
        self._c_instance.set_firmware_version(self._handshake.firmware_version)
        if self._handshake.has_version_requirements(1, 16):
            self._user.settings = self._settings
        else:
            settings = copy(self._settings)
            del settings['aftertouch_threshold']
            self._user.settings = settings

    @listens('failure')
    def _on_handshake_failure(self, bootloader_mode):
        logger.error('Handshake failed, performing harakiri!')
        if bootloader_mode:
            self._c_instance.set_firmware_version(0.0)
        self._c_instance.playhead.enabled = False
        self.elements.playhead_element.proxied_object = NullPlayhead()
        self._note_repeat.set_note_repeat(None)
        self._accent_component.set_full_velocity(None)
        for control in self.controls:
            receive_value_backup = getattr(control, 'receive_value', nop)
            send_midi_backup = getattr(control, 'send_midi', nop)
            try:
                control.receive_value = nop
                if receive_value_backup != nop:
                    control._receive_value_backup = receive_value_backup
                control.send_midi = nop
                if send_midi_backup != nop:
                    control._send_midi_backup = send_midi_backup
            except AttributeError:
                pass

    @listens('mode')
    def _on_push_hardware_mode_changed(self, mode):
        if mode == LIVE_MODE:
            if self._start_handshake_task.is_running:
                self._start_handshake()
            elif self._handshake.handshake_succeeded:
                self.update()

    def _create_background_layer(self):
        return super(Push, self)._create_background_layer() + Layer(display_line1='display_line1', display_line2='display_line2', display_line3='display_line3', display_line4='display_line4', in_button='in_button', out_button='out_button', pad_parameters=self._pad_parameter_control)

    def _create_message_box_background_layer(self):
        return super(Push, self)._create_message_box_background_layer() + BackgroundLayer('in_button', 'out_button', priority=consts.MESSAGE_BOX_PRIORITY)

    def _create_track_frozen_layer(self):
        return Layer(display='display_line2', _notification=self._notification.use_full_display(1))

    def _create_notification_component(self):
        return NotificationComponent(display_lines='display_lines', is_root=True, is_enabled=True)

    def _create_message_box_layer(self):
        return Layer(display_line1='display_line1', display_line2='display_line2', display_line3='display_line3', display_line4='display_line4', cancel_button='select_buttons_raw[-1]', priority=consts.MESSAGE_BOX_PRIORITY)

    def _create_clip_mode(self):
        return [self._track_modes, (self._mixer, self._mixer_layer)] + super(Push, self)._create_clip_mode()

    def _create_clip_loop_layer(self):
        return super(Push, self)._create_clip_loop_layer() + Layer(name_display=self.elements.display_line1.subdisplay[:36], value_display=self.elements.display_line2.subdisplay[:36])

    def _create_clip_audio_layer(self):
        return super(Push, self)._create_clip_audio_layer() + Layer(name_display=self.elements.display_line1.subdisplay[36:], value_display=self.elements.display_line2.subdisplay[36:])

    def _create_clip_name_layer(self):
        return super(Push, self)._create_clip_name_layer() + Layer(display='display_line3')

    def _create_session_recording(self):
        return FixedLengthSessionRecordingComponent(fixed_length_setting=self._fixed_length_setting, clip_creator=self._clip_creator, view_controller=self._view_control, name='Session_Recording', is_root=True)

    def _init_track_modes(self):
        self._track_modes = ModesComponent(name='Track_Modes')
        self._track_modes.set_enabled(False)
        self._track_modes.add_mode('stop', AddLayerMode(self._stop_clips, self._stop_track_clips_layer))
        self._track_modes.add_mode('solo', AddLayerMode(self._mixer, self._mixer_solo_layer))
        self._track_modes.add_mode('mute', AddLayerMode(self._mixer, self._mixer_mute_layer))
        self._track_modes.layer = self._create_track_modes_layer()
        self._track_modes.selected_mode = 'mute'

    def _browser_back_to_top(self):
        self._browser_mode.component.back_to_top()

    def _browser_reset_load_memory(self):
        self._browser_mode.component.reset_load_memory()

    def _init_browser(self):

        class BrowserMode(MultiEntryMode):

            def __init__(self, create_browser = nop, *a, **k):
                super(BrowserMode, self).__init__(LazyComponentMode(create_browser), *a, **k)

            def enter_mode(browser_mode_self):
                super(BrowserMode, browser_mode_self).enter_mode()
                self._scales_enabler.selected_mode = 'disabled'

            @property
            def component(self):
                return self._mode.component

        self._browser_mode = BrowserMode(self._create_browser)
        self._browser_hotswap_mode = MultiEntryMode(BrowserHotswapMode(application=self.application()))
        self._on_browse_mode_changed.subject = self.application().view

    def _init_browse_mode(self):
        self._main_modes.add_mode('browse', [self._when_track_is_not_frozen(self._enable_stop_mute_solo_as_modifiers, partial(self._view_control.show_view, 'Browser'), self._browser_back_to_top, self._browser_hotswap_mode, self._browser_mode, self._browser_reset_load_memory)], groups=['add_effect', 'add_track', 'browse'], behaviour=mixin(DynamicBehaviourMixin, CancellableBehaviour)(lambda : not self._browser_hotswap_mode._mode.can_hotswap() and 'add_effect_left'))
        self._main_modes.add_mode('add_effect_right', [self._when_track_is_not_frozen(self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_device_right))], behaviour=mixin(ExcludingBehaviourMixin, CancellableBehaviour)(['add_track', 'browse']), groups=['add_effect'])
        self._main_modes.add_mode('add_effect_left', [self._when_track_is_not_frozen(self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_device_left))], behaviour=mixin(ExcludingBehaviourMixin, CancellableBehaviour)(['add_track', 'browse']), groups=['add_effect'])
        self._main_modes.add_mode('add_instrument_track', [self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_instrument_track)], behaviour=mixin(ExcludingBehaviourMixin, AlternativeBehaviour)(excluded_groups=['browse', 'add_effect'], alternative_mode='add_default_track'), groups=['add_track'])
        self._main_modes.add_mode('add_default_track', [self._enable_stop_mute_solo_as_modifiers, self._browser_back_to_top, LazyComponentMode(self._create_create_default_track)], groups=['add_track'])
        self._main_modes.add_effect_right_button.mode_unselected_color = self._main_modes.add_effect_left_button.mode_unselected_color = self._main_modes.add_instrument_track_button.mode_unselected_color = 'DefaultButton.On'

    @listens('browse_mode')
    def _on_browse_mode_changed(self):
        if not self.application().browser.hotswap_target:
            if self._main_modes.selected_mode == 'browse' or self._browser_hotswap_mode.is_entered:
                self._main_modes.selected_mode = 'device'

    def _create_browser(self):
        state_buttons = self.elements.track_state_buttons.submatrix[:7, :]
        browser = BrowserComponent(name='Browser', is_enabled=False, layer=Layer(encoder_controls='global_param_controls', display_line1='display_line1', display_line2='display_line2', display_line3='display_line3', display_line4='display_line4', enter_button='in_button', exit_button='out_button', select_buttons='select_buttons', state_buttons=state_buttons, shift_button=WithPriority(consts.SHARED_PRIORITY, 'shift_button'), prehear_button='track_state_buttons_raw[7]', _notification=self._notification.use_full_display(2)), make_browser_model=make_browser_model, preferences=self.preferences)
        return browser

    def _create_create_device_right(self):
        return CreateDeviceComponent(name='Create_Device_Right', browser_component=self._browser_mode.component, browser_mode=self._browser_mode, browser_hotswap_mode=self._browser_hotswap_mode, insert_left=False, is_enabled=False)

    def _create_create_device_left(self):
        return CreateDeviceComponent(name='Create_Device_Right', browser_component=self._browser_mode.component, browser_mode=self._browser_mode, browser_hotswap_mode=self._browser_hotswap_mode, insert_left=True, is_enabled=False)

    def _create_create_default_track(self):
        create_default_track = CreateDefaultTrackComponent(name='Create_Default_Track', is_enabled=False)
        create_default_track.options.layer = Layer(display_line='display_line4', label_display_line='display_line3', blank_display_line2='display_line2', blank_display_line1='display_line1', select_buttons='select_buttons', state_buttons='track_state_buttons', priority=consts.DIALOG_PRIORITY)
        return create_default_track

    def _create_create_instrument_track(self):
        return CreateInstrumentTrackComponent(name='Create_Instrument_Track', browser_component=self._browser_mode.component, browser_mode=self._browser_mode, browser_hotswap_mode=self._browser_hotswap_mode, is_enabled=False)

    def _create_device_mode(self):
        return [self._when_track_is_not_frozen(self._enable_stop_mute_solo_as_modifiers, partial(self._view_control.show_view, 'Detail/DeviceChain'), self._device_parameter_component, self._device_navigation, self._device_note_editor_mode)]

    def _create_scales(self):
        scales = InstrumentScalesComponent(note_layout=self._note_layout, is_enabled=False, name='Scales', layer=(BackgroundLayer('display_line1', 'display_line2', priority=consts.DIALOG_PRIORITY), Layer(scale_line1=self.elements.display_line1.subdisplay[:18], scale_line2=self.elements.display_line2.subdisplay[:18], scale_line3=self.elements.display_line3.subdisplay[:9], scale_line4=self.elements.display_line4.subdisplay[:9], top_display_line=self.elements.display_line3.subdisplay[9:], bottom_display_line=self.elements.display_line4.subdisplay[9:], top_buttons='select_buttons', bottom_buttons='track_state_buttons', encoder_controls='global_param_controls', _notification=self._notification.use_single_line(0, get_slice[18:], align_right), priority=consts.DIALOG_PRIORITY), Layer(presets_toggle_button='shift_button')))
        scales.presets_layer = (BackgroundLayer('track_state_buttons', 'global_param_controls', 'display_line1', 'display_line2', priority=consts.DIALOG_PRIORITY), Layer(top_display_line='display_line3', bottom_display_line='display_line4', top_buttons='select_buttons', _notification=self._notification.use_single_line(0), priority=consts.DIALOG_PRIORITY))
        return scales

    def _create_scales_enabler(self):
        return EnablingModesComponent(component=self._create_scales(), enabled_color='DefaultButton.On', is_enabled=False, layer=Layer(cycle_mode_button='scale_presets_button'))

    def _create_drum_component(self):
        return DrumGroupComponent(name='Drum_Group', is_enabled=False, notification_formatter=self._drum_pad_notification_formatter(), quantizer=self._quantize, selector=self._selector)

    def _init_note_settings_component(self):
        self._note_settings_component = NoteSettingsComponent(grid_resolution=self._grid_resolution, is_enabled=False, layer=Layer(top_display_line='display_line1', bottom_display_line='display_line2', info_display_line='display_line3', clear_display_line='display_line4', full_velocity_button='accent_button', priority=consts.MOMENTARY_DIALOG_PRIORITY))

    def _create_note_editor_mode_selector_layer(self):
        return super(Push, self)._create_note_editor_mode_selector_layer() + Layer(display_line='display_line4', priority=consts.MOMENTARY_DIALOG_PRIORITY)

    def _create_note_editor_track_automation_layer(self):
        return super(Push, self)._create_note_editor_track_automation_layer() + Layer(name_display_line='display_line1', graphic_display_line='display_line2', value_display_line='display_line3', priority=consts.MOMENTARY_DIALOG_PRIORITY)

    def _create_note_editor_device_automation_layer(self):
        return super(Push, self)._create_note_editor_device_automation_layer() + Layer(name_display_line='display_line1', value_display_line='display_line2', graphic_display_line='display_line3', priority=consts.MOMENTARY_DIALOG_PRIORITY)

    def _init_stop_clips_action(self):
        self._stop_clips = StopClipComponent(session_ring=self._session_ring, name='Stop_Clip', is_root=True)
        self._stop_clips.layer = Layer(stop_all_clips_button=self._with_shift('global_track_stop_button'))
        self._stop_track_clips_layer = Layer(stop_track_clips_buttons='track_state_buttons')

    def _init_quantize_actions(self):
        self._quantize_settings = QuantizationSettingsComponent(is_enabled=False, layer=(BackgroundLayer('global_param_controls', 'select_buttons', 'track_state_buttons', priority=consts.MOMENTARY_DIALOG_PRIORITY), Layer(swing_amount_encoder='parameter_controls_raw[0]', quantize_to_encoder='parameter_controls_raw[1]', quantize_amount_encoder='parameter_controls_raw[2]', record_quantization_encoder='parameter_controls_raw[7]', record_quantization_toggle_button='track_state_buttons_raw[7]', display_line1='display_line1', display_line2='display_line2', display_line3='display_line3', display_line4='display_line4', priority=consts.MOMENTARY_DIALOG_PRIORITY)))
        self._quantize = self._for_non_frozen_tracks(QuantizationComponent(name='Selected_Clip_Quantize', settings=self._quantize_settings, is_enabled=False, layer=Layer(action_button='quantize_button')), is_root=True)

    def _init_fixed_length(self):
        super(Push, self)._init_fixed_length()
        self._fixed_length_settings_component.layer = (BackgroundLayer('track_state_buttons', 'display_line1', 'display_line2', priority=consts.MOMENTARY_DIALOG_PRIORITY), Layer(length_option_buttons='select_buttons', label_display_line='display_line3', option_display_line='display_line4', _notification=self._notification.use_single_line(1), priority=consts.MOMENTARY_DIALOG_PRIORITY))

    def _create_note_repeat_layer(self):
        return super(Push, self)._create_note_repeat_layer() + Layer(pad_parameters=self._pad_parameter_control, priority=consts.DIALOG_PRIORITY)

    def _create_user_component(self):
        sysex_control = create_sysex_element(sysex.MODE_CHANGE)
        user = UserComponent(value_control=sysex_control, is_root=True)
        user.layer = Layer(action_button='user_button')
        user.settings_layer = Layer(display_line1='display_line1', display_line2='display_line2', display_line3='display_line3', display_line4='display_line4', encoders='global_param_controls')
        user.settings_layer.priority = consts.DIALOG_PRIORITY
        return user

    def _init_value_components(self):
        super(Push, self)._init_value_components()
        self._swing_amount.display.layer = (BackgroundLayer('display_line4', priority=consts.DIALOG_PRIORITY), Layer(label_display='display_line1', value_display='display_line3', graphic_display='display_line2', priority=consts.DIALOG_PRIORITY))
        self._tempo.display.layer = (BackgroundLayer('display_line3', 'display_line4', priority=consts.DIALOG_PRIORITY), Layer(label_display='display_line1', value_display='display_line2', priority=consts.DIALOG_PRIORITY))
        self._master_vol.display.layer = (BackgroundLayer('display_line4', priority=consts.DIALOG_PRIORITY), Layer(label_display='display_line1', value_display='display_line3', graphic_display='display_line2', priority=consts.DIALOG_PRIORITY))
        self._master_cue_vol.display.layer = (BackgroundLayer('display_line4', priority=consts.DIALOG_PRIORITY), Layer(label_display='display_line1', value_display='display_line3', graphic_display='display_line2', priority=consts.DIALOG_PRIORITY))

    def _create_note_mode(self):
        return super(Push, self)._create_note_mode() + [self._global_pad_parameters]

    def _create_note_mode_behaviour(self):
        return self._auto_arm.auto_arm_restore_behaviour(ReenterBehaviour, on_reenter=self._switch_note_mode_layout)

    def _create_session_mode(self):
        return [self._session_overview_mode, self._session_mode, self._session_navigation]

    def _create_session_overview_layer(self):
        return Layer(button_matrix='shifted_matrix')

    def _set_session_skin(self, session):
        session.set_rgb_mode(CLIP_COLOR_TABLE, RGB_COLOR_TABLE, clip_slots_only=True)

    def _on_selected_track_changed(self):
        super(Push, self)._on_selected_track_changed()
        self._main_modes.pop_groups(['add_effect'])

    def _init_main_modes(self):
        super(Push, self)._init_main_modes()
        self.__on_main_mode_button_value.replace_subjects([self.elements.vol_mix_mode_button,
         self.elements.pan_send_mix_mode_button,
         self.elements.single_track_mix_mode_button,
         self.elements.clip_mode_button,
         self.elements.device_mode_button,
         self.elements.browse_mode_button])

    def _create_mixer_layer(self):
        return super(Push, self)._create_mixer_layer() + Layer(track_names_display='display_line4')

    def _create_mixer_pan_send_layer(self):
        return super(Push, self)._create_mixer_pan_send_layer() + Layer(track_names_display='display_line4', pan_send_names_display='display_line1', pan_send_graphics_display='display_line2', selected_track_name_display='display_line3', pan_send_values_display=ComboElement('display_line3', 'any_touch_button'))

    def _create_mixer_volume_layer(self):
        return super(Push, self)._create_mixer_volume_layer() + Layer(track_names_display='display_line4', volume_names_display='display_line1', volume_graphics_display='display_line2', selected_track_name_display='display_line3', volume_values_display=ComboElement('display_line3', 'any_touch_button'))

    def _create_mixer_track_layer(self):
        return super(Push, self)._create_mixer_track_layer() + Layer(selected_track_name_display='display_line3', track_names_display='display_line4')

    def _create_track_mixer_layer(self):
        return super(Push, self)._create_track_mixer_layer() + Layer(name_display_line='display_line1', graphic_display_line='display_line2', value_display_line=ComboElement('display_line3', 'any_touch_button'))

    def _create_device_parameter_layer(self):
        return super(Push, self)._create_device_parameter_layer() + Layer(name_display_line='display_line1', value_display_line='display_line2', graphic_display_line=ComboElement('display_line3', 'any_touch_button'))

    def _create_device_navigation(self):
        return DeviceNavigationComponent(device_bank_registry=self._device_bank_registry, is_enabled=False, session_ring=self._session_ring, layer=Layer(enter_button='in_button', exit_button='out_button', select_buttons='select_buttons', state_buttons='track_state_buttons', display_line='display_line4', _notification=self._notification.use_single_line(2)), info_layer=Layer(display_line1='display_line1', display_line2='display_line2', display_line3='display_line3', display_line4='display_line4', _notification=self._notification.use_full_display(2)), delete_handler=self._delete_component)

    @listens_group('value')
    def __on_main_mode_button_value(self, value, sender):
        if not value:
            self._scales_enabler.selected_mode = 'disabled'

    def _create_controls(self):
        self._create_pad_sensitivity_update()

        class Deleter(object):

            @property
            def is_deleting(_):
                return self._delete_default_component.is_deleting

            def delete_clip_envelope(_, param):
                return self._delete_default_component.delete_clip_envelope(param)

        self.elements = Elements(deleter=Deleter(), undo_handler=self.song, pad_sensitivity_update=self._pad_sensitivity_update, playhead=self._c_instance.playhead)

    def _create_pad_sensitivity_update(self):
        all_pad_sysex_control = create_sysex_element(sysex.ALL_PADS_SENSITIVITY_PREFIX)
        pad_sysex_control = create_sysex_element(sysex.PAD_SENSITIVITY_PREFIX)
        sensitivity_sender = pad_parameter_sender(all_pad_sysex_control, pad_sysex_control)
        self._pad_sensitivity_update = PadUpdateComponent(all_pads=range(64), parameter_sender=sensitivity_sender, default_profile=action_pad_sensitivity, update_delay=TIMER_DELAY, is_root=True)

    def _init_global_pad_parameters(self):
        self._pad_parameter_control = self._with_firmware_version(1, 16, create_sysex_element(sysex.PAD_PARAMETER_PREFIX, default_value=sysex.make_pad_parameter_message()))
        aftertouch_threshold = self._settings['aftertouch_threshold'].value
        self._global_pad_parameters = GlobalPadParameters(aftertouch_threshold=aftertouch_threshold, is_enabled=False, layer=Layer(pad_parameter=self._pad_parameter_control))

    @listens('value')
    def __on_pad_curve(self, _value):
        self._update_pad_params()

    @listens('value')
    def __on_pad_threshold(self, value):
        self._user.set_settings_info_text('' if value >= CRITICAL_THRESHOLD_LIMIT else consts.MessageBoxText.STUCK_PAD_WARNING)
        self._update_pad_params()

    @listens('value')
    def __on_aftertouch_threshold(self, value):
        self._global_pad_parameters.aftertouch_threshold = value

    def _update_pad_params(self):
        new_pad_parameters = make_pad_parameters(self._settings['curve'].value, self._settings['threshold'].value)
        self._pad_sensitivity_update.set_profile('instrument', new_pad_parameters)
        self._pad_sensitivity_update.set_profile('drums', new_pad_parameters)

    def _update_calibration(self):
        self._send_midi(sysex.CALIBRATION_SET)

    def update(self):
        self._update_calibration()
        super(Push, self).update()
class DS1(LividControlSurface):


	_sysex_id = 16
	_model_name = 'DS1'


	def __init__(self, c_instance):
		super(DS1, self).__init__(c_instance)
		self._skin = Skin(DS1Colors)
		with self.component_guard():
			self._define_sysex()
			self._setup_controls()
			self._setup_background()
			self._setup_m4l_interface()
			self._setup_session_control()
			self._setup_mixer_control()
			self._setup_transport_control()
			self._setup_device_control()
			self._setup_session_recording_component()
			self._setup_main_modes()
	

	def _initialize_script(self):
		super(DS1, self)._initialize_script()
		self._main_modes.set_enabled(True)
		self._main_modes.selected_mode = 'Main'
	

	def _initialize_hardware(self):
		super(DS1, self)._initialize_hardware()
		self.local_control_off.enter_mode()
		self.encoder_absolute_mode.enter_mode()
		self.encoder_speed_sysex.enter_mode()
	


	def _define_sysex(self):
		self.encoder_speed_sysex = SendLividSysexMode(livid_settings = self._livid_settings, call = 'set_encoder_mapping', message = ENCODER_SPEED)
		self.encoder_absolute_mode = SendLividSysexMode(livid_settings = self._livid_settings, call = 'set_encoder_encosion_mode', message = [2])
		self.local_control_off = SendLividSysexMode(livid_settings = self._livid_settings, call = 'set_local_control', message = [0])

	

	def _setup_controls(self):
		is_momentary = True
		optimized = True
		resource = PrioritizedResource
		self._fader = [MonoEncoderElement(mapping_feedback_delay = -1, msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = DS1_FADERS[index], name = 'Fader_' + str(index), num = index, script = self, optimized_send_midi = optimized, resource_type = resource) for index in range(8)]
		self._dial = [[MonoEncoderElement(mapping_feedback_delay = -1, msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = DS1_DIALS[x][y], name = 'Dial_' + str(x) + '_' + str(y), num = x + (y*5), script = self, optimized_send_midi = optimized, resource_type = resource) for x in range(8)] for y in range(5)]
		self._side_dial = [MonoEncoderElement(mapping_feedback_delay = -1, msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = DS1_SIDE_DIALS[x], name = 'Side_Dial_' + str(x), num = x, script = self, optimized_send_midi = optimized, resource_type = resource) for x in range(4)]
		self._encoder = [MonoEncoderElement(mapping_feedback_delay = -1, msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = DS1_ENCODERS[x], name = 'Encoder_' + str(x), num = x, script = self, optimized_send_midi = optimized, resource_type = resource) for x in range(4)]
		self._encoder_button = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = DS1_ENCODER_BUTTONS[index], name = 'EncoderButton_' + str(index), script = self, skin = self._skin, optimized_send_midi = optimized, resource_type = resource) for index in range(4)]
		self._master_fader = MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = DS1_MASTER, name = 'MasterFader', num = 0, script = self, optimized_send_midi = optimized, resource_type = resource)
		self._button = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = DS1_BUTTONS[index], name = 'Button_' + str(index), script = self, skin = self._skin, optimized_send_midi = optimized, resource_type = resource) for index in range(16)]
		self._grid = [[MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = DS1_GRID[x][y], name = 'Button_' + str(x) + '_' + str(y), script = self, skin = self._skin, optimized_send_midi = optimized, resource_type = resource) for x in range(3)] for y in range(3)]
		self._dummy = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = 120+x, name = 'Dummy_Dial_' + str(x), num = x, script = self, optimized_send_midi = optimized, resource_type = resource) for x in range(5)]

		self._fader_matrix = ButtonMatrixElement(name = 'FaderMatrix', rows = [self._fader])
		self._top_buttons = ButtonMatrixElement(name = 'TopButtonMatrix', rows = [self._button[:8]])
		self._bottom_buttons = ButtonMatrixElement(name = 'BottomButtonMatrix', rows = [self._button[8:]])
		self._dial_matrix = ButtonMatrixElement(name = 'DialMatrix', rows = self._dial)
		self._side_dial_matrix = ButtonMatrixElement(name = 'SideDialMatrix', rows = [self._side_dial])
		self._encoder_matrix = ButtonMatrixElement(name = 'EncoderMatrix', rows = [self._encoder])
		self._encoder_button_matrix = ButtonMatrixElement(name = 'EncoderButtonMatrix', rows = [self._encoder_button])
		self._grid_matrix = ButtonMatrixElement(name = 'GridMatrix', rows = self._grid)
		self._selected_parameter_controls = ButtonMatrixElement(name = 'SelectedParameterControls', rows = [self._dummy + self._encoder[:1] + self._encoder[2:]])
	

	def _setup_background(self):
		self._background = BackgroundComponent(name = 'Background')
		self._background.layer = Layer(priority = 0, fader_matrix = self._fader_matrix, 
													top_buttons = self._top_buttons,
													bottom_buttons = self._bottom_buttons,
													dial_matrix = self._dial_matrix,
													side_dial_matrix = self._side_dial_matrix,
													encoder_button_matrix = self._encoder_button_matrix,
													grid_matrix = self._grid_matrix)
		self._background.set_enabled(True)
	

	def _setup_autoarm(self):
		self._auto_arm = AutoArmComponent(name='Auto_Arm')
		self._auto_arm.can_auto_arm_track = self._can_auto_arm_track
	

	def _tracks_to_use(self):
		return self.song.visible_tracks + self.song.return_tracks
	

	def _setup_session_control(self):
		self._session_ring = SessionRingComponent(num_tracks = 8, num_scenes = 1, tracks_to_use = self._tracks_to_use)
		self._session_ring.set_enabled(True)

		self._session_navigation = DS1SessionNavigationComponent(name = 'SessionNavigation', session_ring = self._session_ring)
		self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation.layer = Layer(priority = 4, track_select_dial = ComboElement(control = self._encoder[1], modifier = [self._encoder_button[1]] ), up_button = self._grid[0][1], down_button = self._grid[0][2])
		self._session_navigation.set_enabled(False)
		
		self._session = DS1SessionComponent(session_ring = self._session_ring, auto_name = True)
		hasattr(self._session, '_enable_skinning') and self._session._enable_skinning()
		self._session.layer = Layer(priority = 4, scene_launch_buttons = self._grid_matrix.submatrix[1:2, 1:2])
		self._session.clips_layer = AddLayerMode(self._session, Layer(priority = 4, clip_launch_buttons = self._top_buttons, stop_track_clip_buttons = self._bottom_buttons))
		self._session.set_enabled(False)
	

	def _setup_mixer_control(self):

		self._mixer = MonoMixerComponent(name = 'Mixer', num_returns = 2, tracks_provider = self._session_ring, track_assigner = simple_track_assigner, invert_mute_feedback = True, auto_name = True, enable_skinning = True)
		self._mixer.master_strip().set_volume_control(self._master_fader)
		self._mixer.set_prehear_volume_control(self._side_dial[3])
		self._mixer.layer = Layer(volume_controls = self._fader_matrix, track_select_dial = self._encoder[1])
		self._strip = [self._mixer.channel_strip(index) for index in range(8)]
		for index in range(8):
			self._strip[index].layer = Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[index:index+1, :])
		self._mixer.selected_strip().layer = Layer(priority = 4, parameter_controls = self._selected_parameter_controls)
		self._mixer.master_strip().layer = Layer(priority = 4, parameter_controls = self._side_dial_matrix.submatrix[:3, :])
		self._mixer.main_layer = AddLayerMode(self._mixer, Layer(priority = 4, solo_buttons = self._bottom_buttons, mute_buttons = self._top_buttons))
		self._mixer.select_layer = AddLayerMode(self._mixer, Layer(priority = 4, arm_buttons = self._bottom_buttons, track_select_buttons = self._top_buttons))
		self.song.view.selected_track = self._mixer.channel_strip(0)._track 
		self._mixer.set_enabled(False)
	

	def _setup_transport_control(self):
		self._transport = DS1TransportComponent()
		self._transport.name = 'Transport'
		self._transport._record_toggle.view_transform = lambda value: 'Transport.RecordOn' if value else 'Transport.RecordOff'
		self._transport.layer = Layer(priority = 4, stop_button = self._grid[1][0], play_button = self._grid[0][0], record_button = self._grid[2][0])
		self._transport.set_enabled(True)
	

	def _setup_device_control(self):
		self._device = DeviceComponent(name = 'Device_Component', device_provider = self._device_provider, device_bank_registry = DeviceBankRegistry())

		self._device_navigator = DeviceNavigator(self._device_provider, self._mixer, self)
		self._device_navigator.name = 'Device_Navigator'
	

	def _setup_session_recording_component(self):
		self._clip_creator = ClipCreator()
		self._clip_creator.name = 'ClipCreator'
		self._recorder = SessionRecordingComponent(ViewControlComponent())
		self._recorder.set_enabled(True)
		self._recorder.layer = Layer(priority = 4, automation_button = self._grid[1][2], record_button  = self._grid[2][1],)
	

	def _setup_m4l_interface(self):
		self._m4l_interface = M4LInterfaceComponent(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 _setup_translations(self):
		controls = []
		for control in self.controls:
			controls.append(control)
		self._translations = TranslationComponent(controls, 10)
		self._translations.name = 'TranslationComponent'
		self._translations.set_enabled(False)
	

	def _setup_main_modes(self):
		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('Main', [self._mixer, self._mixer.main_layer, self._session, self._session_navigation], cycle_mode_button_color = 'ModeButtons.Main')
		self._main_modes.add_mode('Select', [self._mixer, self._mixer.select_layer, self._session, self._session_navigation], cycle_mode_button_color = 'ModeButtons.Select')
		self._main_modes.add_mode('Clips', [self._mixer, self._session, self._session.clips_layer, self._session_navigation], cycle_mode_button_color = 'ModeButtons.Clips')
		self._main_modes.layer = Layer(priority = 4, cycle_mode_button = self._grid[2][2])
		self._main_modes.selected_mode = 'Main'
		self._main_modes.set_enabled(False)
	

	def _can_auto_arm_track(self, track):
		routing = track.current_input_routing
		return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith('DS1 Input')
		#self._main_modes.selected_mode in ['Sends', 'Device'] and
	

#	a
Example #7
0
class Minim(LividControlSurface):

    _sysex_id = 18
    _model_name = 'Minim'

    def __init__(self, c_instance, *a, **k):
        super(Minim, self).__init__(c_instance, *a, **k)
        self._shift_latching = LatchingShiftedBehaviour if SHIFT_LATCHING else ShiftedBehaviour
        self._skin = Skin(MinimColors)
        with self.component_guard():
            self._define_sysex()
            self._setup_monobridge()
            self._setup_controls()
            self._setup_background()
            self._setup_autoarm()
            self._setup_viewcontrol()
            self._setup_session()
            self._setup_mixer()
            self._setup_transport()
            self._setup_recorder()
            self._setup_instrument()
            self._setup_modes()
            self._setup_m4l_interface()
        self.log_message(
            '<<<<<<<<<<<<<<<<<<<<<<<<< Minim log opened >>>>>>>>>>>>>>>>>>>>>>>>>'
        )
        self.show_message('Minim Control Surface Loaded')
        self._background.set_enabled(True)

    def _check_connection(self):
        if not self._connected:
            debug(self._model_name, '_check_connection')
            self._livid_settings.new_query_surface()
            #self._connection_routine.restart()
            self.schedule_message(5, self._check_connection)

    def _initialize_hardware(self):
        debug('sending local control off')
        self.local_control_off.enter_mode()

    def _initialize_script(self):
        self._on_device_changed.subject = self._device_provider
        self._main_modes.set_enabled(True)
        self._main_modes.selected_mode = 'session'
        self._session_ring._update_highlight()
        self.refresh_state()

    def _setup_controls(self):
        is_momentary = True
        optimized = False
        resource = PrioritizedResource
        self._fader = MonoEncoderElement(msg_type=MIDI_CC_TYPE,
                                         channel=CHANNEL,
                                         identifier=MINIM_SLIDER,
                                         name='Fader',
                                         script=self,
                                         mapping_feedback_delay=-1,
                                         optimized_send_midi=optimized,
                                         resource_type=resource)
        self._pad = [[
            MonoButtonElement(is_momentary=is_momentary,
                              msg_type=MIDI_NOTE_TYPE,
                              channel=CHANNEL,
                              identifier=MINIM_PADS[row][column],
                              name='Pad_' + str(column) + '_' + str(row),
                              script=self,
                              skin=self._skin,
                              color_map=COLOR_MAP,
                              optimized_send_midi=optimized,
                              resource_type=resource) for column in range(4)
        ] for row in range(2)]
        self._button = [[
            MonoButtonElement(is_momentary=is_momentary,
                              msg_type=MIDI_NOTE_TYPE,
                              channel=CHANNEL,
                              identifier=MINIM_BUTTONS[row][column],
                              name='Button_' + str(column) + '_' + str(row),
                              script=self,
                              skin=self._skin,
                              color_map=COLOR_MAP,
                              optimized_send_midi=optimized,
                              resource_type=resource) for column in range(4)
        ] for row in range(2)]
        self._side_button = [
            MonoButtonElement(is_momentary=is_momentary,
                              msg_type=MIDI_NOTE_TYPE,
                              channel=CHANNEL,
                              identifier=MINIM_SIDE_BUTTONS[index],
                              name='Side_Button_' + str(index),
                              script=self,
                              skin=self._skin,
                              color_map=COLOR_MAP,
                              optimized_send_midi=optimized,
                              resource_type=resource) for index in range(5)
        ]
        self._top_button = [
            MonoButtonElement(is_momentary=is_momentary,
                              msg_type=MIDI_NOTE_TYPE,
                              channel=CHANNEL,
                              identifier=MINIM_TOP_BUTTONS[index],
                              name='Top_Button_' + str(index),
                              script=self,
                              skin=self._skin,
                              color_map=COLOR_MAP,
                              optimized_send_midi=optimized,
                              resource_type=resource) for index in range(2)
        ]
        self._bottom_button = MonoButtonElement(is_momentary=is_momentary,
                                                msg_type=MIDI_NOTE_TYPE,
                                                channel=CHANNEL,
                                                identifier=MINIM_BOTTOM_BUTTON,
                                                name='Bottom_Button',
                                                script=self,
                                                skin=self._skin,
                                                color_map=COLOR_MAP,
                                                optimized_send_midi=optimized,
                                                resource_type=resource)

        self._matrix = ButtonMatrixElement(name='Pad_Matrix',
                                           rows=[
                                               self._button[:][0],
                                               self._pad[:][0],
                                               self._pad[:][1],
                                               self._button[:][1]
                                           ])
        self._side_button_matrix = ButtonMatrixElement(
            name='Side_Button_Matrix', rows=[self._side_button])
        self._top_button_matrix = ButtonMatrixElement(name='Button_Matrix',
                                                      rows=[self._top_button])

    def _setup_background(self):
        self._background = BackgroundComponent()
        self._background.layer = Layer(
            priority=3,
            matrix=self._matrix.submatrix[:, :],
            side_buttons=self._side_button_matrix,
            top_buttons=self._top_button_matrix.submatrix[:, :],
            bottom_button=self._bottom_button)
        self._background.set_enabled(False)

    def _define_sysex(self):
        self._livid_settings = LividSettings(model=18, control_surface=self)
        self.local_control_off = SendLividSysexMode(
            livid_settings=self._livid_settings,
            call='set_local_control',
            message=[42, 42])

    def _setup_autoarm(self):
        self._auto_arm = AutoArmComponent(name='Auto_Arm')
        self._auto_arm.can_auto_arm_track = self._can_auto_arm_track
        self._auto_arm._update_notification = lambda: None

    def _setup_viewcontrol(self):
        self._viewcontrol = ViewControlComponent()
        self._viewcontrol.layer = Layer(priority=4,
                                        prev_track_button=self._top_button[0],
                                        next_track_button=self._top_button[1])
        self._viewcontrol.set_enabled(False)

    def _setup_transport(self):
        self._transport = TransportComponent(name='Transport')
        self._transport.layer = Layer(
            priority=4, play_button=self._side_button[0]
        )  #, overdub_button = self._side_button[1])
        self._transport.set_enabled(False)

    def _setup_mixer(self):
        self._mixer = MonoMixerComponent(
            name='Mixer',
            tracks_provider=self._session_ring,
            track_assigner=SimpleTrackAssigner(),
            invert_mute_feedback=True,
            auto_name=True,
            enable_skinning=True,
            channel_strip_component_type=MonoChannelStripComponent)
        self._mixer._selected_strip.layer = Layer(priority=4,
                                                  volume_control=self._fader)
        self._mixer.solo_mute_record_stop_layer = AddLayerMode(
            self._mixer,
            Layer(
                priority=4,
                mute_buttons=self._matrix.submatrix[:, 0],
                solo_buttons=self._matrix.submatrix[:, 1],
                arm_buttons=self._matrix.submatrix[:, 2],
            ))
        self._mixer.select_layer = AddLayerMode(
            self._mixer,
            Layer(priority=4,
                  arming_track_select_buttons=self._matrix.submatrix[:, 3]))
        self._mixer.mute_layer = AddLayerMode(
            self._mixer,
            Layer(priority=4, mute_buttons=self._matrix.submatrix[:, 3]))

    def _setup_session(self):
        self._session_ring = SessionRingComponent(name='Session_Ring',
                                                  num_tracks=4,
                                                  num_scenes=4)

        self._session = SessionComponent(name='Session',
                                         session_ring=self._session_ring,
                                         auto_name=True)
        self._session.cliplaunch_layer = AddLayerMode(
            self._session,
            Layer(priority=4,
                  clip_launch_buttons=self._matrix.submatrix[:, :]))
        self._session.stop_layer = AddLayerMode(
            self._session,
            Layer(priority=4,
                  stop_track_clip_buttons=self._matrix.submatrix[:, 3]))

        self._session_navigation = SessionNavigationComponent(
            name='Session_Navigation', session_ring=self._session_ring)
        self._session_navigation._horizontal_layer = AddLayerMode(
            self._session_navigation,
            Layer(priority=4,
                  left_button=self._top_button[0],
                  right_button=self._top_button[1]))
        self._session_navigation._vertical_layer = AddLayerMode(
            self._session_navigation,
            Layer(priority=4,
                  up_button=self._top_button[0],
                  down_button=self._top_button[1]))
        self._session_navigation.set_enabled(False)

    def _setup_recorder(self):
        self._recorder = SessionRecordingComponent(
            view_controller=self._viewcontrol)
        self._recorder.layer = Layer(priority=4,
                                     new_button=self._side_button[2],
                                     record_button=self._side_button[1])
        self._recorder.set_enabled(False)

    def _setup_instrument(self):
        self._grid_resolution = GridResolution()

        self._c_instance.playhead.enabled = True
        self._playhead_element = PlayheadElement(self._c_instance.playhead)

        self._drum_group_finder = PercussionInstrumentFinder(
            device_parent=self.song.view.selected_track)

        self._instrument = MinimMonoInstrumentComponent(
            name='InstrumentComponent',
            script=self,
            skin=self._skin,
            drum_group_finder=self._drum_group_finder,
            grid_resolution=self._grid_resolution,
            settings=DEFAULT_INSTRUMENT_SETTINGS,
            device_provider=self._device_provider,
            parent_task_group=self._task_group)
        self._instrument._drumpad._drumgroup._button_coordinates_to_pad_index = lambda first_note, coordinates: coordinates[
            1] + (abs(coordinates[0] - 1) * 4) + first_note
        self._instrument._drumpad._drumgroup.create_translation_entry = lambda button: (
            button.coordinate[1], button.coordinate[
                0] + 2, button.identifier, button.channel)

        self._instrument.layer = Layer(priority=6,
                                       shift_button=self._side_button[3])

        self._instrument.keypad_options_layer = AddLayerMode(
            self._instrument,
            Layer(
                priority=6,
                scale_up_button=self._button[0][3],
                scale_down_button=self._button[0][2],
                offset_up_button=self._button[0][1],
                offset_down_button=self._button[0][0],
            ))
        #vertical_offset_up_button = self._top_button[1],
        #vertical_offset_down_button = self._top_button[0]))
        self._instrument.drumpad_options_layer = AddLayerMode(
            self._instrument,
            Layer(
                priority=6,
                scale_up_button=self._button[0][3],
                scale_down_button=self._button[0][2],
                drum_offset_up_button=self._button[0][1],
                drum_offset_down_button=self._button[0][0],
            ))

        self._instrument._keypad.main_layer = LayerMode(
            self._instrument._keypad,
            Layer(priority=6, keypad_matrix=self._matrix.submatrix[:, 1:3]))
        self._instrument._keypad.select_layer = LayerMode(
            self._instrument._keypad,
            Layer(priority=6,
                  keypad_select_matrix=self._matrix.submatrix[:, 1:3]))

        self._instrument._drumpad.main_layer = LayerMode(
            self._instrument._drumpad,
            Layer(priority=6, drumpad_matrix=self._matrix.submatrix[:, 1:3]))
        self._instrument._drumpad.select_layer = LayerMode(
            self._instrument._drumpad,
            Layer(priority=6,
                  drumpad_select_matrix=self._matrix.submatrix[:, 1:3]))

        self._instrument._main_modes = ModesComponent(name='InstrumentModes')
        self._instrument._main_modes.add_mode('disabled', [])
        self._instrument._main_modes.add_mode('drumpad', [
            self._instrument._drumpad, self._instrument._drumpad.main_layer,
            self._instrument.drumpad_options_layer
        ])
        self._instrument._main_modes.add_mode('drumpad_shifted', [
            self._instrument._drumpad, self._instrument._drumpad.select_layer,
            self._instrument.drumpad_options_layer
        ])
        self._instrument._main_modes.add_mode('keypad', [
            self._instrument._keypad, self._instrument._keypad.main_layer,
            self._instrument.keypad_options_layer
        ])
        self._instrument._main_modes.add_mode('keypad_shifted', [
            self._instrument._keypad, self._instrument._keypad.select_layer,
            self._instrument.keypad_options_layer
        ])
        #self._instrument.register_component(self._instrument._main_modes)

        self._instrument.set_enabled(False)
        #self._instrument.audioloop_layer = LayerMode(self._instrument, Layer(priority = 6, loop_selector_matrix = self._base_grid))

    def _setup_modes(self):
        self._main_modes = ModesComponent(name='MainModes')
        self._main_modes.add_mode('disabled', [])
        self._main_modes.add_mode(
            'session_shifted', [
                self._recorder, self._mixer,
                self._mixer.solo_mute_record_stop_layer, self._session,
                self._session.stop_layer, self._session_navigation,
                self._session_navigation._vertical_layer, self._transport
            ],
            groups=['shifted'],
            behaviour=self._shift_latching(color='Mode.Session'))
        self._main_modes.add_mode(
            'session', [
                self._recorder, self._mixer, self._session,
                self._session.cliplaunch_layer, self._session_navigation,
                self._session_navigation._horizontal_layer, self._transport
            ],
            behaviour=self._shift_latching(color='Mode.Session'))
        self._main_modes.add_mode(
            'instrument_shifted', [
                self._recorder, self._mixer, self._mixer.mute_layer,
                self._viewcontrol, self._instrument, self._transport
            ],
            groups=['shifted'],
            behaviour=self._shift_latching(color='Mode.Instrument'))
        self._main_modes.add_mode(
            'instrument', [
                self._recorder, self._mixer, self._mixer.select_layer,
                self._viewcontrol, self._instrument, self._transport
            ],
            behaviour=self._shift_latching(color='Mode.Instrument'))

        self._main_modes.layer = Layer(priority=6,
                                       session_button=self._side_button[4],
                                       instrument_button=self._side_button[3])
        self._main_modes.set_enabled(False)
        self._main_modes.selected_mode = 'disabled'

    def _can_auto_arm_track(self, track):
        routing = track.current_input_routing
        return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith(
            'Livid Minim Input')

    def _setup_m4l_interface(self):
        self._m4l_interface = M4LInterfaceComponent(
            controls=self.controls, component_guard=self.component_guard)
        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

    @listens('device')
    def _on_device_changed(self):
        pass

    def disconnect(self):
        self.log_message(
            '<<<<<<<<<<<<<<<<<<<<<<<<< Minim log closed >>>>>>>>>>>>>>>>>>>>>>>>>'
        )
        super(Minim, self).disconnect()

    def handle_sysex(self, midi_bytes):
        #debug('sysex: ', str(midi_bytes))
        #debug('matching:', midi_bytes[1:5], 'to', tuple([0, 1, 97]  + [self._sysex_id]))
        if len(midi_bytes) == 9 and midi_bytes[1:5] == tuple([0, 1, 97] +
                                                             [self._sysex_id]):
            if not self._connected:
                #debug('connecting from sysex...')
                self._connected = True
                self._initialize_hardware()
                self._initialize_script()
Example #8
0
class Launchpad_X(InstrumentControlMixin, NovationBase):
    model_family_code = ids.LP_X_FAMILY_CODE
    element_class = Elements
    channel_strip_class = ChannelStripComponent
    session_recording_class = mixin(SessionRecordingMixin,
                                    SessionRecordingComponent)
    track_recording_class = mixin(SessionRecordingMixin,
                                  TrackRecordingComponent)
    target_track_class = ArmedTargetTrackComponent
    skin = skin

    def __init__(self, *a, **k):
        self._last_layout_byte = sysex.SESSION_LAYOUT_BYTE
        (super(Launchpad_X, self).__init__)(*a, **k)

    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_byte)
        self._target_track_changed()
        self._drum_group_changed()
        self.set_feedback_channels(
            [DRUM_FEEDBACK_CHANNEL, SCALE_FEEDBACK_CHANNEL])
        super(Launchpad_X, self).on_identified(midi_bytes)

    def _create_components(self):
        super(Launchpad_X, self)._create_components()
        self._background = BackgroundComponent(name='Background',
                                               add_nop_listeners=True)
        self._session_layout_mode = partial(
            self._elements.layout_switch.send_value, sysex.SESSION_LAYOUT_BYTE)
        self._create_recording_modes()
        self._create_mixer_modes()
        self._create_session_modes()
        self._create_note_modes()
        self._create_main_modes()
        self._mixer.set_send_controls = nop
        self._Launchpad_X__on_layout_switch_value.subject = self._elements.layout_switch

    def _create_mixer_modes(self):
        self._mixer_modes = ModesComponent(
            name='Mixer_Modes',
            is_enabled=False,
            enable_skinning=True,
            layer=Layer(
                volume_button=(self._elements.scene_launch_buttons_raw[0]),
                pan_button=(self._elements.scene_launch_buttons_raw[1]),
                send_a_button=(self._elements.scene_launch_buttons_raw[2]),
                send_b_button=(self._elements.scene_launch_buttons_raw[3]),
                stop_button=(self._elements.scene_launch_buttons_raw[4]),
                mute_button=(self._elements.scene_launch_buttons_raw[5]),
                solo_button=(self._elements.scene_launch_buttons_raw[6]),
                arm_button=(self._elements.scene_launch_buttons_raw[7])))
        bottom_row = self._elements.clip_launch_matrix.submatrix[:, 7:8]
        select_none_mode = partial(setattr, self._mixer_modes, 'selected_mode',
                                   'none')
        self._mixer_modes.add_mode('none', self._session_layout_mode)
        button_fader_layout_mode = partial(
            self._elements.layout_switch.send_value, sysex.FADERS_LAYOUT_BYTE)

        def add_fader_mode(name, color, is_pan=False):
            control_dict = {'{}_controls'.format(name): 'button_faders'}
            if is_pan:
                control_dict[
                    'track_color_controls'] = 'button_fader_color_elements'
            else:
                control_dict[
                    'static_color_controls'] = 'button_fader_color_elements'
            self._mixer_modes.add_mode(
                name, (partial(
                    self._elements.button_fader_setup_element.send_value,
                    sysex.FADER_HORIZONTAL_ORIENTATION
                    if is_pan else sysex.FADER_VERTICAL_ORIENTATION,
                    sysex.FADER_BIPOLAR if is_pan else sysex.FADER_UNIPOLAR),
                       partial(self._mixer.set_static_color_value, color),
                       self._clear_send_cache_of_button_fader_color_elements,
                       AddLayerMode(self._mixer, Layer(**control_dict)),
                       button_fader_layout_mode),
                behaviour=ReenterBehaviour(on_reenter=select_none_mode))

        add_fader_mode('volume', Rgb.GREEN.midi_value)
        add_fader_mode('pan', 0, True)
        add_fader_mode('send_a', Rgb.VIOLET.midi_value)
        add_fader_mode('send_b', Rgb.DARK_BLUE.midi_value)
        self._mixer_modes.add_mode(
            'stop', (self._session_layout_mode,
                     AddLayerMode(self._session,
                                  Layer(stop_track_clip_buttons=bottom_row))),
            behaviour=ReenterBehaviour(on_reenter=select_none_mode))
        self._mixer_modes.add_mode(
            'mute',
            (self._session_layout_mode,
             AddLayerMode(self._mixer, Layer(mute_buttons=bottom_row))),
            behaviour=ReenterBehaviour(on_reenter=select_none_mode))
        self._mixer_modes.add_mode(
            'solo',
            (self._session_layout_mode,
             AddLayerMode(self._mixer, Layer(solo_buttons=bottom_row))),
            behaviour=ReenterBehaviour(on_reenter=select_none_mode))
        self._mixer_modes.add_mode(
            'arm', (self._session_layout_mode,
                    AddLayerMode(self._mixer, Layer(arm_buttons=bottom_row))),
            behaviour=ReenterBehaviour(on_reenter=select_none_mode))
        self._mixer_modes.selected_mode = 'none'

    def _clear_send_cache_of_button_fader_color_elements(self):
        for element in self._elements.button_fader_color_elements_raw:
            element.clear_send_cache()

    def _create_session_modes(self):
        self._session_overview = SessionOverviewComponent(
            name='Session_Overview',
            is_enabled=False,
            session_ring=(self._session_ring),
            enable_skinning=True,
            layer=Layer(button_matrix='clip_launch_matrix'))
        self._session_modes = SessionModesComponent(
            name='Session_Modes',
            is_enabled=False,
            layer=Layer(
                cycle_mode_button='session_mode_button',
                mode_button_color_control='session_button_color_element'))
        self._session_modes.add_mode(
            'launch',
            AddLayerMode(self._session,
                         Layer(scene_launch_buttons='scene_launch_buttons')))
        self._session_modes.add_mode(
            'mixer', DelayMode(self._mixer_modes, SESSION_MODES_SWITCH_DELAY))
        (self._session_modes.add_mode(
            'overview',
            (self._session_layout_mode, self._session_overview,
             AddLayerMode(
                 self._session_navigation,
                 Layer(page_up_button='up_button',
                       page_down_button='down_button',
                       page_left_button='left_button',
                       page_right_button='right_button')),
             AddLayerMode(
                 self._background,
                 Layer(scene_launch_buttons='scene_launch_buttons')))), )
        self._session_modes.selected_mode = 'launch'

    def _create_note_modes(self):
        self._drum_group = DrumGroupComponent(
            name='Drum_Group',
            is_enabled=False,
            translation_channel=DRUM_FEEDBACK_CHANNEL,
            layer=Layer(matrix='drum_pads',
                        scroll_up_button='left_button',
                        scroll_down_button='right_button',
                        scroll_page_up_button='up_button',
                        scroll_page_down_button='down_button'))
        self._scale_pad_translator = ConfigurablePlayableComponent(
            SCALE_FEEDBACK_CHANNEL,
            name='Scale_Pads',
            is_enabled=False,
            layer=Layer(matrix='scale_pads'))
        self._note_modes = ModesComponent(name='Note_Modes', is_enabled=False)
        self._note_modes.add_mode(
            'scale', (self._scale_pad_translator,
                      AddLayerMode((self._background),
                                   layer=Layer(up_button='up_button',
                                               down_button='down_button',
                                               left_button='left_button',
                                               right_button='right_button'))))
        self._note_modes.add_mode('drum', self._drum_group)
        self._note_modes.selected_mode = 'scale'
        self._Launchpad_X__on_note_mode_changed.subject = self._note_modes

    def _create_main_modes(self):
        self._main_modes = ModesComponent(
            name='Main_Modes',
            is_enabled=False,
            layer=Layer(session_button='session_mode_button',
                        note_button='note_mode_button',
                        custom_button='custom_mode_button'))
        self._main_modes.add_mode('session', (self._session_modes),
                                  behaviour=(ImmediateBehaviour()))
        self._main_modes.add_mode('note', (self._note_modes),
                                  behaviour=(ImmediateBehaviour()))
        self._main_modes.add_mode('custom',
                                  None,
                                  behaviour=(ImmediateBehaviour()))
        self._main_modes.selected_mode = 'session'
        self._main_modes.set_enabled(True)
        self._Launchpad_X__on_main_mode_changed.subject = self._main_modes

    @listens('selected_mode')
    def __on_main_mode_changed(self, mode):
        self._recording_modes.selected_mode = 'track' if mode == 'note' else 'session'
        if mode == 'session':
            self._session_modes.revert_to_main_mode()
        self._update_controlled_track()
        self._elements.layout_switch.enquire_value()

    @listens('selected_mode')
    def __on_note_mode_changed(self, mode):
        if self._note_modes.is_enabled():
            self._update_controlled_track()

    @listens('value')
    def __on_layout_switch_value(self, value):
        self._last_layout_byte = value

    def _drum_group_changed(self):
        drum_group = self._drum_group_finder.drum_group
        drum_groud_valid = liveobj_valid(drum_group)
        self._drum_group.set_drum_group_device(drum_group)
        self._elements.note_layout_switch.send_value(
            sysex.DRUM_LAYOUT_BYTE if drum_groud_valid else sysex.
            SCALE_LAYOUT_BYTE)
        self._note_modes.selected_mode = 'drum' if drum_groud_valid else 'scale'

    def _is_instrument_mode(self):
        return self._main_modes.selected_mode == 'note'

    def _feedback_velocity_changed(self, feedback_velocity):
        self._elements.scale_feedback_switch.send_value(feedback_velocity)
class Launchpad_Mini_MK3(NovationBase):
    model_family_code = ids.LP_MINI_MK3_FAMILY_CODE
    element_class = Elements
    skin = skin

    def __init__(self, *a, **k):
        self._last_layout_byte = sysex.SESSION_LAYOUT_BYTE
        (super(Launchpad_Mini_MK3, self).__init__)(*a, **k)

    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_byte)
        super(Launchpad_Mini_MK3, self).on_identified(midi_bytes)

    def _create_components(self):
        super(Launchpad_Mini_MK3, self)._create_components()
        self._create_background()
        self._create_stop_solo_mute_modes()
        self._create_session_modes()
        self._Launchpad_Mini_MK3__on_layout_switch_value.subject = self._elements.layout_switch

    def _create_session_layer(self):
        return super(Launchpad_Mini_MK3, self)._create_session_layer() + Layer(scene_launch_buttons='scene_launch_buttons')

    def _create_stop_solo_mute_modes(self):
        self._stop_solo_mute_modes = ModesComponent(name='Stop_Solo_Mute_Modes',
          is_enabled=False,
          support_momentary_mode_cycling=False,
          layer=Layer(cycle_mode_button=(self._elements.scene_launch_buttons_raw[7])))
        bottom_row = self._elements.clip_launch_matrix.submatrix[:, 7:8]
        self._stop_solo_mute_modes.add_mode('launch',
          None, cycle_mode_button_color='Mode.Launch.On')
        self._stop_solo_mute_modes.add_mode('stop',
          (AddLayerMode(self._session, Layer(stop_track_clip_buttons=bottom_row))),
          cycle_mode_button_color='Session.StopClip')
        self._stop_solo_mute_modes.add_mode('solo',
          (AddLayerMode(self._mixer, Layer(solo_buttons=bottom_row))),
          cycle_mode_button_color='Mixer.SoloOn')
        self._stop_solo_mute_modes.add_mode('mute',
          (AddLayerMode(self._mixer, Layer(mute_buttons=bottom_row))),
          cycle_mode_button_color='Mixer.MuteOff')
        self._stop_solo_mute_modes.selected_mode = 'launch'
        self._stop_solo_mute_modes.set_enabled(True)

    def _create_session_modes(self):
        self._session_overview = SessionOverviewComponent(name='Session_Overview',
          is_enabled=False,
          session_ring=(self._session_ring),
          enable_skinning=True,
          layer=Layer(button_matrix='clip_launch_matrix'))
        self._session_modes = SessionModesComponent(name='Session_Modes',
          is_enabled=False,
          layer=Layer(cycle_mode_button='session_mode_button',
          mode_button_color_control='session_button_color_element'))
        self._session_modes.add_mode('launch', None)
        self._session_modes.add_mode('overview', (
         self._session_overview,
         AddLayerMode(self._session_navigation, Layer(page_up_button='up_button',
           page_down_button='down_button',
           page_left_button='left_button',
           page_right_button='right_button')),
         AddLayerMode(self._background, Layer(scene_launch_buttons='scene_launch_buttons'))))
        self._session_modes.selected_mode = 'launch'
        self._session_modes.set_enabled(True)
        self._Launchpad_Mini_MK3__on_session_mode_changed.subject = self._session_modes

    def _create_background(self):
        self._background = NotifyingBackgroundComponent(name='Background',
          is_enabled=False,
          add_nop_listeners=True,
          layer=Layer(drums_mode_button='drums_mode_button',
          keys_mode_button='keys_mode_button',
          user_mode_button='user_mode_button'))
        self._background.set_enabled(True)
        self._Launchpad_Mini_MK3__on_background_control_value.subject = self._background

    @listens('selected_mode')
    def __on_session_mode_changed(self, _):
        self._elements.layout_switch.enquire_value()

    @listens('value')
    def __on_background_control_value(self, control, value):
        if value:
            if 'Mode' in control.name:
                self._elements.layout_switch.enquire_value()

    @listens('value')
    def __on_layout_switch_value(self, value):
        self._last_layout_byte = value
Example #10
0
class Cntrlr(Base_Cntrlr):
    def __init__(self, *a, **k):
        super(Cntrlr, self).__init__(*a, **k)
        self._skin = Skin(CntrlrColors)
        for button in self._grid:
            button._skin = self._skin
        for button in self._button:
            button._skin = self._skin
        for button in self._encoder_button:
            button._skin = self._skin
        self._main_modes.selected_mode = 'FrederikMode'
        self._on_detail_clip_changed.subject = self.song.view
        self._on_selected_scene_changed.subject = self.song.view
        #self.set_feedback_channels(range(0, 15))
        #self.schedule_message(10, self.initialize_frederik_mode)

    @listens(u'selected_scene')
    def _on_selected_scene_changed(self):
        self._scene_scroller.update()

    def initialize_frederik_mode(self):
        self._main_modes.selected_mode = "FrederikMode"

    def _open_log(self):
        self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) +
                         " for Frederik Poisquet " + str(self._version_check) +
                         " log opened =>>>>>>>>>>>>>>>>>>>")
        self.show_message(str(self._host_name) + ' Control Surface Loaded')

    def _initialize_script(self):
        super(Cntrlr, self)._initialize_script()
        self._connected = True
        #self._main_modes.selected_mode = 'FrederikMode'
        #self._main_modes.set_enabled(True)
        #self._instrument.set_enabled(True)
        self._main_modes.selected_mode = 'disabled'
        self._main_modes.selected_mode = 'FrederikMode'
        #self._session_ring._update_highlight()

    def _define_sysex(self):
        self.encoder_navigation_on = SendLividSysexMode(
            livid_settings=self._livid_settings,
            call='set_encoder_encosion_mode',
            message=[0, 0, 0, 0])

    def _setup_session_control(self):
        self._session_ring = SessionRingComponent(num_tracks=4, num_scenes=4)
        self._session_ring.set_enabled(False)

        self._session_navigation = CntrlrSessionNavigationComponent(
            name='SessionNavigation', session_ring=self._session_ring)

        self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._vertical_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
        self._session_navigation._vertical_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
        self._session_navigation._horizontal_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
        self._session_navigation._horizontal_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'

        self._session_navigation.bank_dial_layer = AddLayerMode(
            self._session_navigation, Layer(priority=5, ))
        self._session_navigation.nav_dial_layer = AddLayerMode(
            self._session_navigation, Layer(priority=5, ))
        self._session_navigation.select_dial_layer = AddLayerMode(
            self._session_navigation, Layer(priority=5))
        self._session_navigation.nav_layer = AddLayerMode(
            self._session_navigation, Layer(priority=5, ))

        self._session_navigation.set_enabled(False)

        self._session = SessionComponent(session_ring=self._session_ring,
                                         auto_name=True)
        hasattr(self._session,
                '_enable_skinning') and self._session._enable_skinning()
        self._session.clip_launch_layer = LayerMode(
            self._session,
            Layer(priority=5, stop_all_clips_button=self._button[27]))
        self._session.stop_all_clips_layer = AddLayerMode(
            self._session,
            Layer(priority=6, stop_all_clips_button=self._button[27]))
        self._session.scene_launch_layer = AddLayerMode(
            self._session._selected_scene,
            Layer(priority=5, stop_all_clips_button=self._button[27]))
        self._session.set_enabled(False)

        self._session_zoom = SessionOverviewComponent(
            name='SessionZoom',
            session_ring=self._session_ring,
            enable_skinning=True)
        self._session_zoom.layer = Layer(priority=5, )
        self._session_zoom.set_enabled(False)

        self._session_ring2 = SessionRingComponent(num_tracks=4,
                                                   num_scenes=1,
                                                   set_session_highlight=nop)
        self._session_ring2.set_enabled(False)

        self._session2 = SpecialSessionComponent(
            session_ring=self._session_ring2, auto_name=True)
        self._session2._selected_scene.layer = Layer(
            priority=5, launch_button=self._button[30])
        self._session2.layer = Layer(
            priority=5,
            stop_all_clips_button=self._button[27],
            fire_next_scene_button=self._button[31]
        )  #, fire_scene_button = self._button[28])

        self._scene_scroller = ScrollComponent(
            scrollable=SelectedSceneScroller(song=self.song))
        self._scene_scroller.layer = Layer(priority=5,
                                           scroll_up_button=self._button[29],
                                           scroll_down_button=self._button[28])
        self._scene_scroller.set_enabled(False)

    def _setup_mixer_control(self):
        super(Cntrlr, self)._setup_mixer_control()
        self._mixer.main_faders_layer = AddLayerMode(self._mixer,
                                                     Layer(priority=5, ))
        self._mixer.main_buttons_layer = AddLayerMode(self._mixer,
                                                      Layer(priority=5, ))
        self._mixer.solo_buttons_layer = AddLayerMode(self._mixer,
                                                      Layer(priority=5, ))
        self._mixer.shifted_buttons_layer = AddLayerMode(
            self._mixer, Layer(priority=5, ))
        self._mixer.main_knobs_layer = AddLayerMode(self._mixer,
                                                    Layer(priority=5, ))
        self._mixer.master_fader_layer = AddLayerMode(
            self._mixer.master_strip(), Layer(priority=5, ))
        self._mixer.instrument_buttons_layer = AddLayerMode(
            self._mixer, Layer(priority=5, ))
        self._mixer.stop_layer = AddLayerMode(self._mixer, Layer(priority=5, ))
        self._mixer.set_enabled(False)

    def _setup_transport_control(self):
        super(Cntrlr, self)._setup_transport_control()
        self._transport.layer = Layer(priority=5, )

    def _setup_session_recording_component(self):
        super(Cntrlr, self)._setup_session_recording_component()
        self._recorder.main_layer = AddLayerMode(self._recorder,
                                                 Layer(priority=5, ))
        self._recorder.shift_layer = AddLayerMode(self._recorder,
                                                  Layer(priority=5, ))
        self._recorder.set_enabled(False)

    def _setup_device_control(self):
        super(Cntrlr, self)._setup_device_control()
        self._device.dial_layer = AddLayerMode(self._device,
                                               Layer(priority=5, ))
        self._device.button_layer = AddLayerMode(self._device,
                                                 Layer(priority=5, ))
        self._device_navigator.select_dial_layer = AddLayerMode(
            self._device_navigator, Layer(priority=5, ))
        self._device_navigator.main_layer = AddLayerMode(
            self._device_navigator, Layer(priority=5, ))

    def _setup_device_selector(self):
        super(Cntrlr, self)._setup_device_selector()
        self._device_selector.select_layer = AddLayerMode(
            self._device_selector, Layer(priority=6, ))
        self._device_selector.assign_layer = AddLayerMode(
            self._device_selector, Layer(priority=7, ))

    def _setup_viewcontrol(self):
        super(Cntrlr, self)._setup_viewcontrol()
        self._view_control.main_layer = AddLayerMode(self._view_control,
                                                     Layer(priority=6, ))

    def _update_modswitcher(self):
        debug('update modswitcher', self.modhandler.active_mod())
        self._modswitcher.selected_mode = 'instrument'

    def _setup_translations(self):
        super(Cntrlr, self)._setup_translations()
        self._setup_translations2()

    def _setup_translations2(self):
        self._translated_controls2 = self._knobs + self._button[
            16:28] + self._fader + self._encoder + self._encoder_button

        self._translations2 = TranslationComponent(self._translated_controls2,
                                                   user_channel_offset=15,
                                                   channel=15)
        self._translations2.name = 'TranslationComponent'
        self._translations2.layer = Layer(priority=10, )
        self._translations2.set_enabled(True)

    def _setup_instrument(self):
        super(Cntrlr, self)._setup_instrument()
        self._instrument._main_modes._mode_map['audioloop'] = _ModeEntry(
            mode=tomode(self._audioloop_pass),
            cycle_mode_button_color=None,
            behaviour=self._instrument._main_modes.default_behaviour,
            groups=set())
        self._instrument.shift_button_layer = AddLayerMode(
            self._instrument, Layer(priority=5, ))
        self._instrument._drumpad._step_sequencer._loop_selector._follow_task.restart(
        )
        #self._instrument._drumpad._step_sequencer._playhead_component._feedback_channels = range(16)

    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._drum_group_finder = PercussionInstrumentFinder(
            device_parent=self.song.view.selected_track)

        self._instrument = CntrlrMonoInstrumentComponent(
            name='InstrumentComponent',
            is_enabled=True,
            script=self,
            skin=self._skin,
            grid_resolution=self._grid_resolution,
            drum_group_finder=self._drum_group_finder,
            parent_task_group=self._task_group,
            settings=DEFAULT_INSTRUMENT_SETTINGS,
            device_provider=self._device_provider)
        self._instrument.shift_button_layer = AddLayerMode(
            self._instrument, Layer(priority=5, ))
        self._instrument.audioloop_layer = AddLayerMode(
            self._instrument,
            Layer(
                priority=5,
                loop_selector_matrix=self._key_matrix.submatrix[:, 0],
            ))

        self._instrument.keypad_shift_layer = AddLayerMode(
            self._instrument,
            Layer(priority=5,
                  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=5,
                  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.sequencer_layer = LayerMode(
            self._instrument._keypad,
            Layer(
                priority=5,
                playhead=self._playhead_element,
                keypad_matrix=self._matrix.submatrix[:, :],
                sequencer_matrix=self._key_matrix.submatrix[:, 0],
            ))
        self._instrument._keypad.split_layer = LayerMode(
            self._instrument._keypad,
            Layer(priority=5,
                  keypad_matrix=self._matrix.submatrix[:, :],
                  split_matrix=self._key_matrix.submatrix[:14, 0]))
        self._instrument._keypad.sequencer_shift_layer = LayerMode(
            self._instrument._keypad,
            Layer(
                priority=5,
                keypad_select_matrix=self._matrix.submatrix[:, :],
                loop_selector_matrix=self._key_matrix.submatrix[:8, 0],
                quantization_buttons=self._key_matrix.submatrix[:8, 1],
            ))
        #follow_button = self._button[23]))
        self._instrument._keypad.sequencer_session_layer = LayerMode(
            self._instrument._keypad,
            Layer(priority=5,
                  playhead=self._playhead_element,
                  sequencer_matrix=self._key_matrix.submatrix[:, :1]))
        self._instrument._keypad.split_session_layer = LayerMode(
            self._instrument._keypad,
            Layer(priority=5,
                  split_matrix=self._key_matrix.submatrix[:16, :1]))
        self._instrument._keypad.sequencer_session_shift_layer = LayerMode(
            self._instrument._keypad,
            Layer(
                priority=5,
                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.sequencer_layer = LayerMode(
            self._instrument._drumpad,
            Layer(
                priority=5,
                playhead=self._playhead_element,
                drumpad_matrix=self._matrix.submatrix[:, :],
                sequencer_matrix=self._key_matrix.submatrix[:, 0],
            ))
        self._instrument._drumpad.split_layer = LayerMode(
            self._instrument._drumpad,
            Layer(priority=5,
                  drumpad_matrix=self._matrix.submatrix[:, :],
                  split_matrix=self._key_matrix.submatrix[:16, :1]))
        self._instrument._drumpad.sequencer_shift_layer = LayerMode(
            self._instrument._drumpad,
            Layer(
                priority=5,
                drumpad_select_matrix=self._matrix.submatrix[:, :],
                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.sequencer_session_layer = LayerMode(
            self._instrument._drumpad,
            Layer(priority=5,
                  sequencer_matrix=self._key_matrix.submatrix[:, :1]))
        self._instrument._drumpad.split_session_layer = LayerMode(
            self._instrument._drumpad,
            Layer(priority=5,
                  split_matrix=self._key_matrix.submatrix[:16, :1]))
        self._instrument._drumpad.sequencer_session_shift_layer = LayerMode(
            self._instrument._drumpad,
            Layer(
                priority=5,
                loop_selector_matrix=self._key_matrix.submatrix[:8, :1],
                quantization_buttons=self._key_matrix.submatrix[:8, 1:],
            ))  #follow_button = self._button[23]))
        #self._instrument.set_session_mode_button(self._button[30])

    def _setup_modes(self):

        common = CompoundMode(self._mixer, self._session_ring)
        main_buttons = CompoundMode(self._mixer.main_buttons_layer,
                                    self._transport, self._recorder,
                                    self._recorder.main_layer, self._device,
                                    self._device.button_layer)
        shifted_main_buttons = CompoundMode(
            self._mixer.solo_buttons_layer, self._recorder,
            self._recorder.shift_layer, self._session,
            self._session.scene_launch_layer, self._device,
            self._device.button_layer)
        main_faders = CompoundMode(self._mixer.main_faders_layer,
                                   self._mixer.master_fader_layer)
        main_dials = CompoundMode(self._view_control,
                                  self._view_control.main_layer, self._device,
                                  self._device.dial_layer,
                                  self._device_navigator.select_dial_layer,
                                  self.encoder_navigation_on)
        shifted_dials = CompoundMode(self._session_navigation,
                                     self._session_navigation.nav_dial_layer,
                                     self._device, self._device.dial_layer,
                                     self._device_navigator.select_dial_layer,
                                     self.encoder_navigation_on)

        self._modalt_mode = ModesComponent(name='ModAltMode')
        self._modalt_mode.add_mode('disabled', None)
        self._modalt_mode.add_mode(
            'enabled', [tuple([self._enable_mod_alt, self._disable_mod_alt])],
            behaviour=CancellableBehaviourWithRelease(),
            cycle_mode_button_color='Mod.AltOn')
        self._modalt_mode.selected_mode = 'disabled'
        self._modalt_mode.set_enabled(False)
        self._modalt_mode.layer = Layer(priority=5,
                                        enabled_button=self._encoder_button[1])

        self._modswitcher = ModesComponent(name='ModSwitcher')
        self._modswitcher.add_mode('mod', [
            self.modhandler, self._modalt_mode, main_faders,
            self._mixer.main_knobs_layer, self._device,
            self._device.dial_layer, self._device_navigator.main_layer,
            main_dials,
            DelayMode(self.modhandler.update,
                      delay=.5,
                      parent_task_group=self._task_group)
        ])
        self._modswitcher.add_mode('instrument', [
            self._instrument,
            self._instrument.shift_button_layer,
            main_buttons,
            main_faders,
            self._mixer.main_knobs_layer,
            self._device,
            self._device.dial_layer,
            self._device.button_layer,
            self._device_navigator.main_layer,
        ])  #self._instrument.shift_button_layer, self._optional_translations])
        self._modswitcher.selected_mode = 'instrument'
        self._modswitcher.set_enabled(False)

        self._instrument._main_modes = ModesComponent(parent=self._instrument,
                                                      name='InstrumentModes')
        self._instrument._main_modes.add_mode('disabled', [])
        self._instrument._main_modes.add_mode('drumpad', [
            self._instrument._drumpad.sequencer_layer, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_split', [
            self._instrument._drumpad.split_layer,
            self._instrument._selected_session, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_sequencer', [
            self._instrument._drumpad.sequencer_layer, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_shifted', [])
        self._instrument._main_modes.add_mode('drumpad_split_shifted', [])
        self._instrument._main_modes.add_mode('drumpad_sequencer_shifted', [])
        self._instrument._main_modes.add_mode('keypad', [
            self._instrument._keypad.sequencer_layer, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('keypad_split', [
            self._instrument._keypad.split_layer,
            self._instrument._selected_session, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('keypad_sequencer', [
            self._instrument._keypad.sequencer_layer, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('keypad_shifted', [])
        self._instrument._main_modes.add_mode('keypad_split_shifted', [])
        self._instrument._main_modes.add_mode('keypad_sequencer_shifted', [])
        self._instrument._main_modes.add_mode('drumpad_session', [])
        self._instrument._main_modes.add_mode('drumpad_split_session', [])
        self._instrument._main_modes.add_mode('drumpad_sequencer_session', [])
        self._instrument._main_modes.add_mode('drumpad_shifted_session', [])
        self._instrument._main_modes.add_mode('drumpad_split_shifted_session',
                                              [])
        self._instrument._main_modes.add_mode(
            'drumpad_sequencer_shifted_session', [])
        self._instrument._main_modes.add_mode('keypad_session', [])
        self._instrument._main_modes.add_mode('keypad_split_session', [])
        self._instrument._main_modes.add_mode('keypad_sequencer_session', [])
        self._instrument._main_modes.add_mode('keypad_shifted_session', [])
        self._instrument._main_modes.add_mode('keypad_split_shifted_session',
                                              [])
        self._instrument._main_modes.add_mode(
            'keypad_sequencer_shifted_session', [])

        self._instrument._main_modes.add_mode('audioloop', [
            self._instrument.audioloop_layer,
        ])
        self._instrument._main_modes.add_mode('audioloop_shifted', [
            self._instrument.audioloop_layer,
        ])

        self._instrument._main_modes.selected_mode = 'disabled'
        self._instrument.set_enabled(True)

        self._main_modes = ModesComponent(name='MainModes')
        self._main_modes.add_mode('disabled', [self._background])
        self._main_modes.add_mode('MixMode', [
            common,
            self._instrument,
            self._instrument.shift_button_layer,
            self._mixer,
            main_faders,
            self._mixer.main_knobs_layer,
            self._device,
            self._device_navigator,
            self._device_navigator.main_layer,
        ])
        self._main_modes.add_mode(
            'ModSwitcher', [
                common, main_faders, main_dials, self._mixer.main_knobs_layer,
                self._session_navigation.select_dial_layer, self._view_control,
                self._view_control.main_layer,
                self._device_navigator.select_dial_layer,
                self.encoder_navigation_on, self._modswitcher,
                DelayMode(self._update_modswitcher, delay=.1)
            ],
            behaviour=ColoredCancellableBehaviourWithRelease(
                color='ModeButtons.ModSwitcher',
                off_color='ModeButtons.ModSwitcherDisabled'))
        self._main_modes.add_mode(
            'Translations', [
                common, main_faders, main_dials, self._mixer.main_knobs_layer,
                DelayMode(self._translations, delay=.1),
                DelayMode(self._translations.selector_layer, delay=.3)
            ],
            behaviour=DefaultedBehaviour(
                default_mode='MixMode',
                color='ModeButtons.Translations',
                off_color='ModeButtons.TranslationsDisabled'))
        self._main_modes.add_mode(
            'DeviceSelector', [
                common, self._device_selector,
                DelayMode(self._device_selector.select_layer, delay=.1),
                DelayMode(self.modhandler.lock_layer, delay=.1),
                DelayMode(self._device_selector.assign_layer,
                          delay=.5), main_buttons, main_dials, main_faders,
                self._mixer.main_knobs_layer, self._device,
                self._device_navigator
            ],
            behaviour=ColoredCancellableBehaviourWithRelease(
                color='ModeButtons.DeviceSelector',
                off_color='ModeButtons.DeviceSelectorDisabled'))
        self._main_modes.add_mode('FrederikMode', [
            self._instrument, self._scene_scroller, self._session2,
            self._translations2
        ])
        self._main_modes.layer = Layer(priority=5)
        self._main_modes.selected_mode = 'FrederikMode'
        self._main_modes.set_enabled(True)
        #self._test.subject = self._instrument._main_modes

    @listens(u'detail_clip')
    def _on_detail_clip_changed(self):
        self._instrument._drumpad._step_sequencer._loop_selector._follow_task.restart(
        )
        #playhead = self._instrument._drumpad._step_sequencer._playhead_component
        #debug('VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV')
        #debug('playhead playhead:', playhead._playhead)
        #debug('playhead clip:', playhead._clip.name if playhead._clip and hasattr(playhead._clip, 'name') else None)
        #debug('playhead notes:', playhead._notes)
        #debug('playhead feedback_channels:', playhead._feedback_channels)
        #debug('enabled:', playhead._playhead.enabled if playhead._playhead and hasattr(playhead._playhead, 'enabled') else 'False')
        #debug('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^')
        #self.schedule_message(2, self.update_playhead)

    @listens('selected_mode')
    def _test(self, *a):
        comps = [
            self._main_modes, self._modswitcher, self._instrument,
            self._instrument._main_modes, self._instrument._matrix_modes,
            self._instrument._selected_session, self._session, self._device,
            self._mixer, self._session_navigation, self._session_zoom,
            self._recorder, self._transport
        ]
        debug('VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV')
        """
		debug('main mode:', self._main_modes.selected_mode)
		debug('instrument mode:', self._instrument._main_modes.selected_mode)
		debug('modswitcher mode:', self._modswitcher.selected_mode)
		debug('instrument matrix mode:', self._instrument._matrix_modes.selected_mode)
		for comp in comps:
			debug(comp.name, 'is enabled:', comp.is_enabled())
		"""
        playhead = self._instrument._drumpad._step_sequencer._note_editor._playhead_component
        debug('playhead playhead:', playhead._playhead)
        debug('playhead clip:', playhead._clip)
        debug('playhead notes:', playhead._notes)
        debug('playhead playhead:', playhead._playhead)
        debug('playhead feedback_channels:', playhead._feedback_channels)
        debug('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^')
Example #11
0
class AumPush2(Push2):


	device_component_class = AumPush2DeviceComponent
	device_provider_class = ModDeviceProvider

	def __init__(self, c_instance, model):
		self._monomod_version = 'b996'
		self._cntrlr_version = 'b996'
		self._host_name = 'AumPush2'
		self._color_type = 'Push'
		self._auto_arm_calls = 0
		self.log_message = logger.warning
		super(AumPush2, self).__init__(c_instance, model)
		with self.component_guard():
			self._hack_stuff()
		#self._on_selected_track_changed.subject = self.song.view
		#self._on_main_mode_changed.subject = self._main_modes
		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<< AumPush2 ' + str(self._monomod_version) + ' log opened >>>>>>>>>>>>>>>>>>>>>>>>') 
	

	def _create_components(self):
		self._remove_pedal()
		super(AumPush2, self)._create_components()
	

	def _create_skin(self):
		return self.register_disconnectable(make_default_skin())
	

	def _setup_mod(self):

		def get_monomodular(host):
				if isinstance(__builtins__, dict):
					if not 'monomodular' in __builtins__.keys() or not isinstance(__builtins__['monomodular'], ModRouter):
						__builtins__['monomodular'] = ModRouter(song = self.song, register_component = self._register_component)
				else:
					if not hasattr(__builtins__, 'monomodular') or not isinstance(__builtins__['monomodular'], ModRouter):
						setattr(__builtins__, 'monomodular', ModRouter(song = self.song, register_component = self._register_component))
				monomodular = __builtins__['monomodular']
				if not monomodular.has_host():
					monomodular.set_host(host)
				return monomodular
		

		self.monomodular = get_monomodular(self)
		self.monomodular.name = 'monomodular_switcher'
		with inject(register_component = const(self._register_component), song = const(self.song)).everywhere():
			self.modhandler = PushModHandler(self) ## song = self.song, register_component = self._register_component)
		self.modhandler.name = 'ModHandler'
		self.modhandler.layer = Layer( priority = 6, lock_button = self.elements.note_mode_button, grid = self.elements.matrix, 
																			nav_up_button = self.elements.octave_up_button, 
																			nav_down_button = self.elements.octave_down_button, 
																			nav_left_button = self.elements.in_button, 
																			nav_right_button = self.elements.out_button,
																			key_buttons = self.elements.side_buttons,
																			)
		self.modhandler.alt_shift_layer = AddLayerMode( self.modhandler, Layer(Shift_button = self.elements.shift_button,
																			Alt_button = self.elements.select_button))
		self.modhandler.legacy_shift_layer = AddLayerMode( self.modhandler, Layer(priority = 7, 
																			device_selector_matrix = self.elements.matrix.submatrix[:, :1],
																			channel_buttons = self.elements.matrix.submatrix[:, 1:2], 
																			nav_matrix = self.elements.matrix.submatrix[4:8, 2:6],
																			))
		self.modhandler.shift_layer = AddLayerMode( self.modhandler, Layer( priority = 7,
																			lock_button = self.elements.master_select_button,
																			))
																			#device_selector_matrix = self.elements.matrix.submatrix[:, :1],
		self.modhandler.alt_layer = AddLayerMode( self.modhandler, Layer( priority = 7, 
																			))
																			#key_buttons = self.elements.select_buttons))
																			#key_buttons = self.elements.track_state_buttons))
		self._device_provider.restart_mod()
	

	def _init_matrix_modes(self):
		super(AumPush2, self)._init_matrix_modes()
		#self._setup_monoinstrument()
		self._setup_mod()
		self._note_modes.add_mode('mod', [self.modhandler, self.modhandler.alt_shift_layer, DelayMode(delay = .1, mode = self.modhandler.nav_update)])
		self._note_modes.add_mode('looperhack', [self._audio_loop])
	

	def _create_device_component(self):
		return self.device_component_class(script = self, device_decorator_factory=self._device_decorator_factory, device_bank_registry=self._device_bank_registry, banking_info=self._banking_info, name='DeviceComponent', is_enabled=True, is_root=True)
	

	def _create_main_mixer_modes(self):

		self._mixer_control = MixerControlComponent(name='Global_Mix_Component', view_model=self._model.mixerView, tracks_provider=self._session_ring, is_enabled=False, layer=Layer(controls='fine_grain_param_controls', volume_button='track_state_buttons_raw[0]', panning_button='track_state_buttons_raw[1]', send_slot_one_button='track_state_buttons_raw[2]', send_slot_two_button='track_state_buttons_raw[3]', send_slot_three_button='track_state_buttons_raw[4]', send_slot_four_button='track_state_buttons_raw[5]', send_slot_five_button='track_state_buttons_raw[6]', cycle_sends_button='track_state_buttons_raw[7]'))
		self._model.mixerView.realtimeMeterData = self._mixer_control.real_time_meter_handlers
		track_mixer_control = TrollMixerControlComponent(script = self, troll_submodes = self._troll_submodes, name='Track_Mix_Component', is_enabled=False, tracks_provider=self._session_ring, layer=Layer(controls='fine_grain_param_controls', scroll_left_button='track_state_buttons_raw[6]', scroll_right_button='track_state_buttons_raw[7]'))
		self._track_mixer_control = track_mixer_control
		#track_mixer_control = TrackMixerControlComponent(name='Track_Mix_Component', is_enabled=False, tracks_provider=self._session_ring, layer=Layer(controls='fine_grain_param_controls', scroll_left_button='track_state_buttons_raw[6]', scroll_right_button='track_state_buttons_raw[7]'))
		routing_control = RoutingControlComponent(is_enabled=False, layer=Layer(monitor_state_encoder='parameter_controls_raw[0]'))
		track_mix_or_routing_chooser = TrackOrRoutingControlChooserComponent(tracks_provider=self._session_ring, track_mixer_component=track_mixer_control, routing_control_component=routing_control, is_enabled=False, layer=Layer(mix_button='track_state_buttons_raw[0]', routing_button='track_state_buttons_raw[1]'))
		self._model.mixerView.trackControlView = track_mix_or_routing_chooser
		self._mix_modes = ModesComponent(is_enabled=False)
		self._mix_modes.add_mode('global', self._mixer_control)
		self._mix_modes.add_mode('track', track_mix_or_routing_chooser)
		self._mix_modes.selected_mode = 'global'
		self._model.mixerSelectView = self._mixer_control
		self._model.trackMixerSelectView = track_mixer_control

		class MixModeBehaviour(ReenterBehaviour):

			def press_immediate(behaviour_self, component, mode):
				if self._is_on_master() and self._mix_modes.selected_mode != 'track':
					self._mix_modes.selected_mode = 'track'
				super(MixModeBehaviour, behaviour_self).press_immediate(component, mode)
			

			def on_reenter(behaviour_self):
				if not self._is_on_master():
					self._mix_modes.cycle_mode()
			

		

		self._main_modes.add_mode('mix', [self._mix_modes, SetAttributeMode(obj=self._note_editor_settings_component, attribute='parameter_provider', value=self._track_parameter_provider)], behaviour=MixModeBehaviour())
	

	def _with_select(self, button):
		return ComboElement(button, [self.elements.select_button])
	

	def _hack_stuff(self):
		crossfader_strip = TouchStripControllerComponent()
		crossfader_strip.layer = Layer(touch_strip = self.elements.touch_strip_control)
		crossfader_strip.set_enabled(False)
		self._crossfader_control = AumPushCrossfader(strip_controller = crossfader_strip, task_group = self._task_group, is_root = True)
		self._crossfader_control.set_enabled(False)
		
		self._device_selector = DeviceSelectorComponent(self)
		self._device_selector._off_value = 64
		self._device_selector.layer = Layer(priority = 9, matrix = self.elements.matrix.submatrix[:, :4])
		self._device_selector.set_enabled(False)

		self._send_reset = AumPushResetSendsComponent(self)
		self._send_reset.layer = Layer(priority = 9, send_a_button = self._with_select(self.elements.track_state_buttons_raw[4]), send_b_button = self._with_select(self.elements.track_state_buttons_raw[5]), send_c_button = self._with_select(self.elements.track_state_buttons_raw[6]), send_d_button = self._with_select(self.elements.track_state_buttons_raw[7]))
		self._send_reset.set_enabled(False)

		self._troll_submodes = ModesComponent()
		self._troll_submodes.add_mode('Strip', [])
		self._troll_submodes.add_mode('FX1', [])
		self._troll_submodes.add_mode('FX2', [])
		self._troll_submodes.add_mode('Inputs', [])
		self._troll_submodes.layer = Layer(priority = 8, Strip_button = 'side_buttons_raw[0]', FX1_button = 'side_buttons_raw[1]', FX2_button = 'side_buttons_raw[2]', Inputs_button = 'side_buttons_raw[3]')
		self._troll_submodes.selected_mode = 'Strip'
		self._troll_submodes.set_enabled(False)

		static_modes = CompoundMode(self._crossfader_control, self._device_selector, self._send_reset, self._troll_submodes)

		self._troll_modes = ModesComponent()
		self._troll_modes.add_mode('disabled', [], cycle_mode_button_color = 'DefaultButton.Off')
		self._troll_modes.add_mode('enabled', [static_modes, tuple([self._grab_track_mode, self._release_track_mode, ])], cycle_mode_button_color = 'DefaultButton.Alert')
		self._troll_modes.layer = Layer(cycle_mode_button = 'master_select_button')
		self._troll_modes.selected_mode = 'disabled'
	

	@listens('selected_mode')
	def _on_main_mode_changed(self, mode):
		debug('main_mode selected mode is now:', mode)
		#if self._troll_modes.selected_mode is 'enabled' and not mode is 'device':
		#	self._troll_modes.selected_mode = 'disabled'
	

	def _init_main_modes(self):
		super(AumPush2, self)._init_main_modes()
		self._on_main_mode_changed.subject = self._main_modes
	

	def _grab_track_mode(self):
		debug('grab device mode')
		"""self._main_modes.pop_unselected_modes()
		if not self._main_modes.selected_mode is 'device':
			self._main_modes.push_mode('device')
		self._device_component._update_parameters()"""
		
		self._track_mixer_control._mode_on_troll_entrance = self._mix_modes.selected_mode
		self._track_mixer_control._main_offset = self._track_mixer_control.scroll_offset
		self._track_mixer_control._scroll_offset = self._track_mixer_control._troll_offset
		if self._main_modes.selected_mode is 'mix':
			self._check_track_mixer_entry()
	

	def _release_track_mode(self):
		debug('release device mode')
		"""if self._troll_modes.selected_mode is 'enabled':
			self._troll_modes.selected_mode = 'disabled'
		if len(self._main_modes.active_modes) > 1:
			self._main_modes.pop_mode('device')
		self._device_component._update_parameters()"""
		
		self._track_mixer_control._troll_offset = self._track_mixer_control.scroll_offset
		self._track_mixer_control._scroll_offset = self._track_mixer_control._main_offset
		if self._main_modes.selected_mode is 'mix':
			self._mix_modes.selected_mode = self._track_mixer_control._mode_on_troll_entrance
			if self._track_mixer_control._mode_on_troll_entrance is 'track':
				self._track_mixer_control.notify_scroll_offset()
				self._track_mixer_control.update()
	

	def _check_track_mixer_entry(self):
		debug('_check_track_mixer_entry')
		if self._troll_modes.selected_mode is 'enabled':
			if not self._mix_modes.selected_mode is 'track':
				#self._mix_modes.push_mode('track')
				self._mix_modes.selected_mode = 'track'
			self._track_mixer_control.notify_scroll_offset()
			self._track_mixer_control.update()
	

	def _check_track_mixer_exit(self):
		debug('_check_track_mixer_exit')
	

	def _disable_troll(self):
		#self._troll_modes.selected_mode = 'disabled'
		debug('disable troll')
	

	def _init_mute_solo_stop(self):
		super(AumPush2, self)._init_mute_solo_stop()
		self._master_selector.layer = Layer(toggle_button=self._with_select('master_select_button'))
	

	def _grab_crossfader(self):
		self._crossfader_strip.set_parameter(self.song.master_track.mixer_device.crossfader)
	

	def _release_crossfader(self):
		self._crossfader_strip.set_parameter(None)
	

	def _remove_pedal(self):

		#self.real_foot_pedal_button = self.elements.foot_pedal_button
		self.elements.foot_pedal_button = DoublePressElement(create_button(127, name = 'Foot_Pedal', skin = self._skin, is_rgb=True))
		for control in self.controls:
			if isinstance(control, ConfigurableButtonElement) and control._original_identifier is 69:
				self.log_message('found control: ' + str(control))
				self.controls.remove(control)
				break
		self.request_rebuild_midi_map()
	

	#in progress: this will allow viewing returns on right side of channel selectors when trollmode is engaged.
	def right_align_return_tracks_track_assigner(song, tracks_provider):
		if self._troll_modes.selected_mode == 'disabled':
			offset = tracks_provider.track_offset
			tracks = tracks_provider.tracks_to_use()
			return_tracks = list(song.return_tracks)
			size = tracks_provider.num_tracks
			num_empty_tracks = max(0, size + offset - len(tracks))
			track_list = size * [None]
			for i in xrange(size):
				track_index = i + offset
				if len(tracks) > track_index:
					track = tracks[track_index]
					empty_offset = 0 if tracks[track_index] not in return_tracks else num_empty_tracks
					track_list[i + empty_offset] = track
		else:
			offset = tracks_provider.track_offset
			tracks = tracks_provider.tracks_to_use()
			return_tracks = list(song.return_tracks)
			size = tracks_provider.num_tracks
			num_empty_tracks = max(0, size + offset - len(tracks))
			track_list = size * [None]
			for i in xrange(size):
				track_index = i + offset
				if len(tracks) > track_index:
					track = tracks[track_index]
					empty_offset = 0 if tracks[track_index] not in return_tracks else num_empty_tracks
					track_list[i + empty_offset] = track

		return track_list
	

	"""
	@listens('device')
	def _on_device_changed(self):
		debug('_on_device_changed')
		#self.schedule_message(1, self._select_note_mode)
		#self._select_note_mode()
	

	@listens('selected_track')
	def _on_selected_track_changed(self):
		#if self._troll_modes.selected_mode is 'enabled':
		#	self._device_component._update_parameters()
		pass
	
	"""

	def _select_note_mode(self, mod_device = None):
		track = self.song.view.selected_track
		drum_device, sliced_simpler = self._percussion_instruments_for_track(track)
		self._drum_component.set_drum_group_device(drum_device)
		self._slicing_component.set_simpler(sliced_simpler)
		debug('select_note_mode: ', self.modhandler.is_locked(), self.modhandler.active_mod(), len(track.devices))
		if not (self._note_modes.selected_mode is 'mod' and self.modhandler.is_locked()):
			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 self.modhandler.active_mod():
				self._note_modes.selected_mode = 'mod'
			elif track and track.has_audio_input:
				self._note_modes.selected_mode = 'looperhack'
			elif drum_device:
				self._note_modes.selected_mode = 'drums'
			elif sliced_simpler:
				self._note_modes.selected_mode = 'slicing'
			else:
				self._note_modes.selected_mode = 'instrument'
			self.reset_controlled_track()
	

	def disconnect(self):
		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<< AumPush2 ' + str(self._monomod_version) + ' log closed >>>>>>>>>>>>>>>>>>>>>>>>') 
		super(AumPush2, self).disconnect()
	

	def _can_auto_arm_track(self, track):
		routing = track.current_input_routing
		return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith('AumPush2')
Example #12
0
class Cntrlr(BaseCntrlr):
    def __init__(self, *a, **k):
        super(Cntrlr, self).__init__(*a, **k)
        self._skin = Skin(CntrlrColors)
        for button in self._grid:
            button._skin = self._skin

    def _open_log(self):
        self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) +
                         " for Georg Oswald " + str(self._version_check) +
                         " log opened =>>>>>>>>>>>>>>>>>>>")
        self.show_message(str(self._host_name) + ' Control Surface Loaded')

    def _setup_transport_control(self):
        super(Cntrlr, self)._setup_transport_control()
        self._transport._overdub_toggle.view_transform = lambda value: 'Transport.OverdubOn' if value else 'Transport.OverdubOff'
        self._transport.layer = Layer(priority=4, play_button=self._button[24])
        self._transport.overdub_layer = AddLayerMode(
            self._transport, Layer(priority=4,
                                   overdub_button=self._button[25]))

    def _setup_session_control(self):
        super(Cntrlr, self)._setup_session_control()
        self._session_navigation.nav_layer = AddLayerMode(
            self._session_navigation,
            Layer(priority=4,
                  page_down_button=self._button[23],
                  page_up_button=self._button[22],
                  page_left_button=self._button[20],
                  page_right_button=self._button[21]))
        self._session.G_layer = AddLayerMode(
            self._session,
            Layer(priority=4,
                  scene_launch_buttons=self._key_matrix.submatrix[4:8, 0]))
        self._session.stop_clips_layer = AddLayerMode(self._session,
                                                      Layer(priority=4, ))
        #stop_all_clips_button = self._button[29],))

    def _setup_session_recording_component(self):
        super(Cntrlr, self)._setup_session_recording_component()
        self._recorder.main_layer = AddLayerMode(self._recorder,
                                                 Layer(priority=4))
        self._recorder.shift_layer = AddLayerMode(
            self._recorder,
            Layer(priority=4, automation_button=self._button[25]))

    def _setup_mixer_control(self):
        super(Cntrlr, self)._setup_mixer_control()

        mute_buttons = ButtonMatrixElement(
            name='mute_buttons', rows=[self._button[:4] + self._button[12:16]])
        select_buttons = ButtonMatrixElement(
            name='select_buttons',
            rows=[self._button[16:20] + self._button[28:32]])

        self._G_session_ring = SessionRingComponent(num_tracks=8, num_scenes=4)
        self._G_session_ring.set_enabled(False)

        self._G_mixer = MonoMixerComponent(
            name='Mixer',
            num_returns=4,
            tracks_provider=self._G_session_ring,
            track_assigner=simple_track_assigner,
            invert_mute_feedback=True,
            auto_name=True,
            enable_skinning=True)

        if FREE_ENCODER_IS_CROSSFADER:
            self._mixer.layer = Layer(priority=4,
                                      crossfader_control=self._encoder[1])
        #self._G_mixer.select_dial_layer = AddLayerMode(self._G_mixer, Layer(priority = 5,
        #									track_select_dial = self._encoder[3],))
        self._G_mixer.main_faders_layer = AddLayerMode(
            self._G_mixer,
            Layer(
                priority=4,
                volume_controls=self._fader_matrix.submatrix[:8, :],
            ))
        self._G_mixer.main_buttons_layer = AddLayerMode(
            self._G_mixer,
            Layer(priority=4,
                  mute_buttons=mute_buttons,
                  arming_track_select_buttons=select_buttons,
                  solo_buttons=self._dial_button_matrix,
                  stop_clip_buttons=self._key_matrix.submatrix[4:12, :1]))
        #solo_buttons = self._key_matrix.submatrix[4:12, :1],))
        self._G_mixer.shifted_buttons_layer = AddLayerMode(
            self._G_mixer, Layer(
                priority=4,
                mute_buttons=mute_buttons,
            ))
        self._G_mixer.solo_buttons_layer = AddLayerMode(
            self._G_mixer,
            Layer(
                priority=4,
                solo_buttons=self._key_matrix.submatrix[4:12, :1],
            ))
        self._G_mixer.mute_buttons_layer = AddLayerMode(
            self._G_mixer, Layer(
                priority=4,
                mute_buttons=mute_buttons,
            ))

        self._G_mixer.stop_layer = AddLayerMode(
            self._G_mixer,
            Layer(
                priority=4,
                stop_clip_buttons=self._key_matrix.submatrix[8:12, 1:],
            ))

        self._G_mixer.main_knobs_layer = AddLayerMode(self._G_mixer,
                                                      Layer(priority=4))

        self._G_mixer.master_fader_layer = AddLayerMode(
            self._G_mixer.master_strip(), Layer(priority=4, ))
        self._G_mixer.instrument_buttons_layer = AddLayerMode(
            self._G_mixer,
            Layer(
                priority=4,
                mute_buttons=mute_buttons,
                track_select_buttons=select_buttons,
            ))
        self._G_mixer.set_enabled(False)

    def _setup_device_control(self):
        super(Cntrlr, self)._setup_device_control()
        self._device.button_layer = AddLayerMode(self._device,
                                                 Layer(priority=4, ))
        self._device_navigator.main_layer = AddLayerMode(
            self._device_navigator, Layer(priority=4, ))
        #prev_button = self._encoder_button[8],
        #next_button = self._encoder_button[9],
        #exit_button = self._encoder_button[10],
        #enter_button = self._encoder_button[11],))
        self._device_navigator.G_layer = AddLayerMode(
            self._device_navigator,
            Layer(
                priority=4,
                prev_button=self._button[28],
                next_button=self._button[29],
            ))

    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._drum_group_finder = PercussionInstrumentFinder(
            device_parent=self.song.view.selected_track)

        self._instrument = CntrlrMonoInstrumentComponent(
            name='InstrumentComponent',
            is_enabled=True,
            script=self,
            skin=self._skin,
            grid_resolution=self._grid_resolution,
            drum_group_finder=self._drum_group_finder,
            parent_task_group=self._task_group,
            settings=DEFAULT_INSTRUMENT_SETTINGS,
            device_provider=self._device_provider)
        self._instrument.shift_button_layer = AddLayerMode(
            self._instrument,
            Layer(priority=5,
                  session_mode_button=self._button[26],
                  shift_mode_button=self._button[27]))
        self._instrument.audioloop_layer = AddLayerMode(
            self._instrument, Layer(priority=5))

        self._instrument.keypad_shift_layer = AddLayerMode(
            self._instrument,
            Layer(
                priority=5,
                scale_up_button=self._button[31],
                scale_down_button=self._button[30],
                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],
            ))

        self._instrument.drumpad_shift_layer = AddLayerMode(
            self._instrument,
            Layer(
                priority=5,
                scale_up_button=self._button[31],
                scale_down_button=self._button[30],
                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],
            ))

        self._instrument._keypad.sequencer_layer = LayerMode(
            self._instrument._keypad,
            Layer(
                priority=5,
                playhead=self._playhead_element,
                keypad_matrix=self._matrix.submatrix[:, :],
            ))
        self._instrument._keypad.split_layer = LayerMode(
            self._instrument._keypad,
            Layer(
                priority=5,
                keypad_matrix=self._matrix.submatrix[:, :],
            ))
        self._instrument._keypad.sequencer_shift_layer = LayerMode(
            self._instrument._keypad,
            Layer(priority=5,
                  keypad_matrix=self._matrix.submatrix[:, :],
                  quantization_buttons=self._key_matrix.submatrix[:7, 1],
                  follow_button=self._button[23]))
        self._instrument._keypad.sequencer_session_layer = LayerMode(
            self._instrument._keypad,
            Layer(
                priority=5,
                playhead=self._playhead_element,
            ))
        self._instrument._keypad.split_session_layer = LayerMode(
            self._instrument._keypad,
            Layer(priority=5,
                  split_matrix=self._key_matrix.submatrix[:16, :1]))
        self._instrument._keypad.sequencer_session_shift_layer = LayerMode(
            self._instrument._keypad,
            Layer(priority=5,
                  quantization_buttons=self._key_matrix.submatrix[:7, 1:],
                  follow_button=self._button[23]))

        self._instrument._drumpad.sequencer_layer = LayerMode(
            self._instrument._drumpad,
            Layer(
                priority=5,
                playhead=self._playhead_element,
                drumpad_matrix=self._matrix.submatrix[:, :],
            ))
        self._instrument._drumpad.split_layer = LayerMode(
            self._instrument._drumpad,
            Layer(priority=5,
                  drumpad_matrix=self._matrix.submatrix[:, :],
                  split_matrix=self._key_matrix.submatrix[:16, :1]))
        self._instrument._drumpad.sequencer_shift_layer = LayerMode(
            self._instrument._drumpad,
            Layer(priority=5,
                  drumpad_matrix=self._matrix.submatrix[:, :],
                  quantization_buttons=self._key_matrix.submatrix[:7, 1:],
                  follow_button=self._button[23]))
        self._instrument._drumpad.sequencer_session_layer = LayerMode(
            self._instrument._drumpad,
            Layer(
                priority=5,
                playhead=self._playhead_element,
            ))
        self._instrument._drumpad.split_session_layer = LayerMode(
            self._instrument._drumpad,
            Layer(priority=5,
                  split_matrix=self._key_matrix.submatrix[:16, :1]))
        self._instrument._drumpad.sequencer_session_shift_layer = LayerMode(
            self._instrument._drumpad,
            Layer(priority=5,
                  quantization_buttons=self._key_matrix.submatrix[:7, 1:],
                  follow_button=self._button[23]))

        #self._instrument.set_session_mode_button(self._button[30])

    def _setup_modes(self):

        common = CompoundMode(self._mixer, self._session_ring)
        main_buttons = CompoundMode(
            self._G_mixer.main_buttons_layer, self._session_navigation,
            self._session_navigation.nav_layer, self._transport,
            self._transport.overdub_layer, self._recorder,
            self._recorder.main_layer, self._device, self._device.button_layer)
        shifted_main_buttons = CompoundMode(
            self._G_mixer.shifted_buttons_layer,
            self._transport,
            self._transport.overdub_layer,
            #self._recorder,
            #self._recorder.shift_layer,
            self._session,
            self._session.G_layer,
            self._session.stop_clips_layer,
            self._transport,
            self._device,
            self._device.button_layer,
            self._device_navigator,
            self._device_navigator.G_layer)
        main_faders = CompoundMode(self._G_mixer,
                                   self._G_mixer.main_faders_layer,
                                   self._G_mixer.master_fader_layer)
        main_dials = CompoundMode(self._view_control,
                                  self._view_control.main_layer, self._device,
                                  self._device.dial_layer,
                                  self._device_navigator,
                                  self._device_navigator.select_dial_layer,
                                  self.encoder_navigation_on)
        shifted_dials = CompoundMode(self._session_navigation,
                                     self._session_navigation.nav_dial_layer,
                                     self._device, self._device.dial_layer,
                                     self._device_navigator,
                                     self._device_navigator.select_dial_layer,
                                     self.encoder_navigation_on)
        self._modalt_mode = ModesComponent(name='ModAltMode')
        self._modalt_mode.add_mode('disabled', None)
        self._modalt_mode.add_mode(
            'enabled', [tuple([self._enable_mod_alt, self._disable_mod_alt])],
            behaviour=CancellableBehaviourWithRelease(),
            cycle_mode_button_color='Mod.AltOn')
        self._modalt_mode.selected_mode = 'disabled'
        self._modalt_mode.set_enabled(False)
        self._modalt_mode.layer = Layer(priority=4,
                                        enabled_button=self._encoder_button[1])

        self._modswitcher = ModesComponent(name='ModSwitcher')
        self._modswitcher.add_mode('mod', [
            self.modhandler, self._modalt_mode, main_faders,
            self._G_mixer.main_knobs_layer, self._device,
            self._device.dial_layer, self._device_navigator.main_layer,
            main_dials,
            DelayMode(self.modhandler.update,
                      delay=.5,
                      parent_task_group=self._task_group)
        ])
        self._modswitcher.add_mode('instrument', [
            self._instrument,
            self._instrument.shift_button_layer,
            main_buttons,
            main_faders,
            self._G_mixer.main_knobs_layer,
            self._device,
            self._device.dial_layer,
            self._device.button_layer,
            self._device_navigator.main_layer,
        ])  #self._instrument.shift_button_layer, self._optional_translations])
        self._modswitcher.selected_mode = 'instrument'
        self._modswitcher.set_enabled(False)

        self._instrument._main_modes = ModesComponent(name='InstrumentModes')
        self._instrument._main_modes.add_mode('disabled', [
            main_buttons, main_dials, self._session, self._session,
            self._session.clip_launch_layer
        ])
        self._instrument._main_modes.add_mode('drumpad', [
            self._instrument._drumpad.sequencer_layer, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_split', [
            self._instrument._drumpad.split_layer,
            self._instrument._selected_session, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_sequencer', [
            self._instrument._drumpad.sequencer_layer, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_shifted', [
            self._instrument._drumpad.sequencer_shift_layer,
            self._instrument.drumpad_shift_layer, shifted_main_buttons,
            shifted_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_split_shifted', [
            self._instrument._drumpad.split_layer,
            self._instrument.drumpad_shift_layer, shifted_main_buttons,
            shifted_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_sequencer_shifted', [
            self._instrument._drumpad.sequencer_shift_layer,
            self._instrument.drumpad_shift_layer, shifted_main_buttons,
            shifted_dials
        ])
        self._instrument._main_modes.add_mode('keypad', [
            self._instrument._keypad.sequencer_layer, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('keypad_split', [
            self._instrument._keypad.split_layer,
            self._instrument._selected_session, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('keypad_sequencer', [
            self._instrument._keypad.sequencer_layer, main_buttons, main_dials
        ])
        self._instrument._main_modes.add_mode('keypad_shifted', [
            self._instrument._keypad.sequencer_shift_layer,
            self._instrument.keypad_shift_layer, shifted_main_buttons,
            shifted_dials
        ])
        self._instrument._main_modes.add_mode('keypad_split_shifted', [
            self._instrument._keypad.split_layer,
            self._instrument.keypad_shift_layer, shifted_main_buttons,
            shifted_dials
        ])
        self._instrument._main_modes.add_mode('keypad_sequencer_shifted', [
            self._instrument._keypad.sequencer_shift_layer,
            self._instrument.keypad_shift_layer, shifted_main_buttons,
            shifted_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_session', [
            self._instrument._drumpad.sequencer_session_layer, main_buttons,
            self._session,
            DelayMode(self._session.clip_launch_layer, delay=.1), main_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_split_session', [
            self._instrument._drumpad.split_session_layer,
            self._instrument._selected_session, main_buttons, self._session,
            DelayMode(self._session.clip_launch_layer, delay=.1), main_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_sequencer_session', [
            self._instrument._drumpad.sequencer_session_layer, main_buttons,
            self._session,
            DelayMode(self._session.clip_launch_layer, delay=.1), main_dials
        ])
        self._instrument._main_modes.add_mode('drumpad_shifted_session', [
            self._instrument._drumpad.sequencer_session_shift_layer,
            self._instrument.drumpad_shift_layer, main_buttons, self._session,
            shifted_dials
        ])
        self._instrument._main_modes.add_mode(
            'drumpad_split_shifted_session', [
                self._instrument._drumpad.split_session_layer,
                self._instrument.drumpad_shift_layer, shifted_main_buttons,
                self._session, shifted_dials
            ])
        self._instrument._main_modes.add_mode(
            'drumpad_sequencer_shifted_session', [
                self._instrument._drumpad.sequencer_session_shift_layer,
                self._instrument.drumpad_shift_layer, shifted_main_buttons,
                self._session, shifted_dials
            ])
        self._instrument._main_modes.add_mode('keypad_session', [
            self._instrument._keypad.sequencer_session_layer, main_buttons,
            self._session,
            DelayMode(self._session.clip_launch_layer, delay=.1), main_dials
        ])
        self._instrument._main_modes.add_mode('keypad_split_session', [
            self._instrument._keypad.split_session_layer,
            self._instrument._selected_session, main_buttons, self._session,
            DelayMode(self._session.clip_launch_layer, delay=.1), main_dials
        ])
        self._instrument._main_modes.add_mode('keypad_sequencer_session', [
            self._instrument._keypad.sequencer_session_layer, main_buttons,
            self._session,
            DelayMode(self._session.clip_launch_layer, delay=.1), main_dials
        ])
        self._instrument._main_modes.add_mode('keypad_shifted_session', [
            self._instrument._keypad.sequencer_session_shift_layer,
            self._instrument.keypad_shift_layer, shifted_main_buttons,
            self._session, shifted_dials
        ])
        self._instrument._main_modes.add_mode('keypad_split_shifted_session', [
            self._instrument._keypad.split_session_layer,
            self._instrument.keypad_shift_layer, shifted_main_buttons,
            self._session, shifted_dials
        ])
        self._instrument._main_modes.add_mode(
            'keypad_sequencer_shifted_session', [
                self._instrument._keypad.sequencer_session_shift_layer,
                self._instrument.keypad_shift_layer, shifted_main_buttons,
                self._session, shifted_dials
            ])

        self._instrument._main_modes.add_mode('audioloop', [
            self._instrument.audioloop_layer, main_buttons, main_dials,
            self._session,
            DelayMode(self._session.clip_launch_layer, delay=.1)
        ])
        self._instrument._main_modes.add_mode('audioloop_shifted', [
            self._instrument.audioloop_layer, shifted_main_buttons,
            self._session, shifted_dials
        ])
        #self._instrument._main_modes.add_mode('audioloop_shifted_session', [self._instrument.audioloop_layer, self._session, shifted_main_buttons, main_dials, shifted_dials])
        self._instrument.register_component(self._instrument._main_modes)
        self._instrument._main_modes.selected_mode = 'disabled'
        self._instrument.set_enabled(True)

        self._main_modes = ModesComponent(name='MainModes')
        self._main_modes.add_mode('disabled', [self._background])
        self._main_modes.add_mode('MixMode', [
            common, self._instrument, self._instrument.shift_button_layer,
            self._G_mixer, main_faders, self._G_mixer.main_knobs_layer,
            self._device, self._device_navigator,
            self._device_navigator.main_layer,
            self._device_navigator.select_dial_layer
        ])
        self._main_modes.add_mode(
            'ModSwitcher', [
                common, main_faders, main_dials,
                self._G_mixer.main_knobs_layer,
                self._session_navigation.select_dial_layer, self._view_control,
                self._view_control.main_layer, self._device_navigator,
                self._device_navigator.select_dial_layer,
                self.encoder_navigation_on, self._modswitcher,
                DelayMode(self._update_modswitcher, delay=.1)
            ],
            behaviour=ColoredCancellableBehaviourWithRelease(
                color='ModeButtons.ModSwitcher',
                off_color='ModeButtons.ModSwitcherDisabled'))
        self._main_modes.add_mode(
            'Translations', [
                common, main_faders, main_dials, self._mixer.main_knobs_layer,
                self._translations,
                DelayMode(self._translations.selector_layer, delay=.1)
            ],
            behaviour=DefaultedBehaviour(
                default_mode='MixMode',
                color='ModeButtons.Translations',
                off_color='ModeButtons.TranslationsDisabled'))
        self._main_modes.add_mode(
            'DeviceSelector', [
                common, self._device_selector,
                DelayMode(self._device_selector.select_layer, delay=.1),
                DelayMode(self.modhandler.lock_layer, delay=.1),
                DelayMode(self._device_selector.assign_layer,
                          delay=.5), main_buttons, main_dials, main_faders,
                self._G_mixer.main_knobs_layer, self._device,
                self._device_navigator
            ],
            behaviour=ColoredCancellableBehaviourWithRelease(
                color='ModeButtons.DeviceSelector',
                off_color='ModeButtons.DeviceSelectorDisabled'))
        self._main_modes.layer = Layer(
            priority=4,
            ModSwitcher_button=self._encoder_button[2],
            DeviceSelector_button=self._encoder_button[0],
            Translations_button=self._encoder_button[3])  #,
        self._main_modes.selected_mode = 'disabled'
        self._main_modes.set_enabled(True)

        self._test.subject = self._instrument._main_modes
Example #13
0
class Launchpad(ControlSurface):
	u""" Script for Novation's Launchpad Controller """

	def __init__(self, c_instance):
		ControlSurface.__init__(self, c_instance)
		is_momentary = True
		self._suppress_send_midi = False
		with self.component_guard():
			self._skin = make_default_skin()
			#with inject(skin=const(self._skin)).everywhere():
			#	self._midimap = MidiMap()
			self._suggested_input_port = u'Launchpad'
			self._suggested_output_port = u'Launchpad'
			self._control_is_with_automap = False
			self._user_byte_write_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 16)
			self._user_byte_write_button.name = u'User_Byte_Button'
			self._user_byte_write_button.send_value(1)
			self._user_byte_write_button.add_value_listener(self._user_byte_value)
			self._wrote_user_byte = False
			self._challenge = Live.Application.get_random_int(0, 400000000) & 2139062143
			self._matrix = ButtonMatrixElement()
			self._matrix.name = u'Button_Matrix'
			#with inject(skin=const(self._skin)).everywhere():
			for row in range(8):
				button_row = []
				for column in range(8):
					button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column, skin = self._skin)
					button.name = str(column) + u'_Clip_' + str(row) + u'_Button'
					button_row.append(button)

				self._matrix.add_row(tuple(button_row))
			self._top_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index, skin = self._skin) for index in range(8) ]
			self._side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], skin = self._skin) for index in range(8) ]
			self._top_matrix = ButtonMatrixElement(name = u'Top_Button_Matrix', rows = [self._top_buttons])
			self._side_matrix = ButtonMatrixElement(name = u'Side_Button_Matrix', rows = [self._side_buttons])

			self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0, optimized_send_midi=False)
			self._config_button.add_value_listener(self._config_value)

			self._top_buttons[0].name = u'Bank_Select_Up_Button'
			self._top_buttons[1].name = u'Bank_Select_Down_Button'
			self._top_buttons[2].name = u'Bank_Select_Left_Button'
			self._top_buttons[3].name = u'Bank_Select_Right_Button'
			self._top_buttons[4].name = u'Session_Button'
			self._top_buttons[5].name = u'User1_Button'
			self._top_buttons[6].name = u'User2_Button'
			self._top_buttons[7].name = u'Mixer_Button'
			self._side_buttons[0].name = u'Vol_Button'
			self._side_buttons[1].name = u'Pan_Button'
			self._side_buttons[2].name = u'SndA_Button'
			self._side_buttons[3].name = u'SndB_Button'
			self._side_buttons[4].name = u'Stop_Button'
			self._side_buttons[5].name = u'Trk_On_Button'
			self._side_buttons[6].name = u'Solo_Button'
			self._side_buttons[7].name = u'Arm_Button'

			self._create_background()
			self._create_translations()
			self._create_session()
			self._create_mixer()
			self._create_modes()
	

	def _create_background(self):
		self._background = BackgroundComponent(name = 'Background')
		self._background.layer = Layer(priority = 5, matrix = self._matrix, side_buttons = self._side_matrix, top_buttons = self._top_matrix)
		self._background.set_enabled(True)
	

	def _create_translations(self):
		self._translations1 = TranslationComponent(name = 'User1Translation', translated_channel=2, should_enable=True, should_reset=True, is_enabled=False, layer=Layer(matrix = self._matrix, top_buttons = self._top_matrix.submatrix[:4,1], side_buttons = self._side_matrix))
		self._translations2 = TranslationComponent(name = 'User2Translation', translated_channel=3, should_enable=True, should_reset=True, is_enabled=False, layer=Layer(matrix = self._matrix, top_buttons = self._top_matrix.submatrix[:4,1], side_buttons = self._side_matrix))
	

	def _create_session(self):
		self._session_ring = SessionRingComponent(8,  8, name = u'Session_Ring')
		self._session = SpecialSessionComponent(session_ring = self._session_ring, name = u'Session', is_enabled = False, auto_name = True)
		self._session_navigation = SessionNavigationComponent(session_ring = self._session_ring, name = u'SessionNavigation', is_enabled = False)
		self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_banking.scroll_up_button.disabled_color = 'Session.NavigationButtonOff'
		self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_banking.scroll_down_button.disabled_color = 'Session.NavigationButtonOff'
		self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_up_button.disabled_color = 'Session.NavigationButtonOff'
		self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_down_button.disabled_color = 'Session.NavigationButtonOff'
		self._session_navigation._vertical_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_up_button.disabled_color = 'Session.PageNavigationButtonOff'
		self._session_navigation._vertical_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_down_button.disabled_color = 'Session.PageNavigationButtonOff'
		self._session_navigation._horizontal_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_up_button.disabled_color = 'Session.PageNavigationButtonOff'
		self._session_navigation._horizontal_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_down_button.disabled_color = 'Session.PageNavigationButtonOff'
		self._zooming = SessionOverviewComponent(session_ring = self._session_ring, enable_skinning = True, name = u'Session_Zooming', is_enabled = False)
		self._zooming.layer = Layer(button_matrix = self._matrix)

		self._session_navigation.nav_layer = AddLayerMode(self._session_navigation, Layer(up_button = self._top_buttons[0], down_button = self._top_buttons[1], left_button = self._top_buttons[2], right_button = self._top_buttons[3]))
		self._session_navigation.page_layer = AddLayerMode(self._session_navigation, Layer(page_up_button = self._top_buttons[0], page_down_button = self._top_buttons[1], page_left_button = self._top_buttons[2], page_right_button = self._top_buttons[3]))
		self._session.cliplaunch_layer = AddLayerMode(self._session, Layer(priority = 1, clip_launch_buttons = self._matrix, scene_launch_buttons = self._side_matrix))
		self._session.clipstop_layer = AddLayerMode(self._session, Layer(priority = 1, stop_all_clips_button = self._side_buttons[4], stop_track_clip_buttons = self._matrix.submatrix[:, 4:5]))

	def _create_mixer(self):
		self._mixer = SpecialMixerComponent(tracks_provider = self._session_ring, auto_name=True, is_enabled=True, invert_mute_feedback=True)
		self._mixer.name = u'Mixer'
		self._mixer.master_strip().name = u'Master_Channel_strip'
		self._mixer.selected_strip().name = u'Selected_Channel_strip'
		self._sliders = []
		self._slider_volume_modes = []
		self._slider_pan_modes = []
		self._slider_single_modes = []
		for column in range(8):
			self._mixer.channel_strip(column).name = u'Channel_Strip_' + str(column)
			self._sliders.append(PreciseButtonSliderElement(buttons = tuple([ self._matrix._orig_buttons[7-row][column]for row in range(8) ])))
			self._sliders[-1].name = u'Button_Slider_' + str(column)
		self._slider_matrix = ButtonMatrixElement(name = u'SliderMatrix', rows = [self._sliders])
		self._mixer.overview_layer = AddLayerMode(self._mixer, Layer(priority = 1, default_volume_buttons = self._matrix.submatrix[:, :1],
																					default_panning_buttons = self._matrix.submatrix[:, 1:2],
																					default_send1_buttons = self._matrix.submatrix[:, 2:3],
																					default_send2_buttons = self._matrix.submatrix[:, 3:4],
																					mute_buttons = self._matrix.submatrix[:, 5:6],
																					solo_buttons = self._matrix.submatrix[:, 6:7],
																					arm_buttons = self._matrix.submatrix[:, 7:8],
																					unarm_all_button = self._side_buttons[7],
																					unsolo_all_button = self._side_buttons[6],
																					unmute_all_button = self._side_buttons[5]))
		self._mixer.volume_layer = AddLayerMode(self._mixer, Layer(priority = 1, volume_controls = self._slider_matrix))
		self._mixer.pan_layer = AddLayerMode(self._mixer, Layer(priority = 1, pan_controls = self._slider_matrix))
		self._mixer.send1_layer = AddLayerMode(self._mixer, Layer(priority = 1, send_controls = self._slider_matrix))
		self._mixer.send2_layer = AddLayerMode(self._mixer, Layer(priority = 1, send_controls = self._slider_matrix))
	

	def _create_modes(self):
		self._session_modes = ModesComponent(name = u'SessionModes')
		self._session_modes.add_mode(u'Session', [self._session, self._session.cliplaunch_layer, self._session_navigation, self._session_navigation.nav_layer], cycle_mode_button_color = u'MainModes.SelectedOn')
		self._session_modes.add_mode(u'Zoom', [self._zooming, self._session_navigation, self._session_navigation.page_layer], cycle_mode_button_color = u'MainModes.SelectedPressed')
		self._session_modes.selected_mode = u'Session'
		self._session_modes.layer = Layer(priority = 1, cycle_mode_button = self._top_buttons[4])
		self._session_modes.set_enabled(False)

		self._mixer_modes = ModesComponent(name = u'MixerModes')
		self._mixer_modes.add_mode(u'Overview', [self._session_navigation, self._session_navigation.nav_layer, self._session, self._session.clipstop_layer, self._mixer, self._mixer.overview_layer])
		self._mixer_modes.add_mode(u'TrackVolume', [self._session_navigation, self._session_navigation.nav_layer, self._mixer, self._mixer.volume_layer, tuple([self.set_slider_volume_mode, self.set_slider_single_mode])])
		self._mixer_modes.add_mode(u'TrackPan', [self._session_navigation, self._session_navigation.nav_layer, self._mixer, self._mixer.pan_layer, tuple([self.set_slider_pan_mode, self.set_slider_single_mode])])
		self._mixer_modes.add_mode(u'TrackSend1', [self._session_navigation, self._session_navigation.nav_layer, self._mixer, self._mixer.send1_layer, SetAttributeMode(obj=self._mixer, attribute=u'send_index', value=0), tuple([self.set_slider_send_mode, self.set_slider_single_mode])])
		self._mixer_modes.add_mode(u'TrackSend2', [self._session_navigation, self._session_navigation.nav_layer, self._mixer, self._mixer.send2_layer, SetAttributeMode(obj=self._mixer, attribute=u'send_index', value=1), tuple([self.set_slider_send_mode, self.set_slider_single_mode])])
		for mode in self._mixer_modes._mode_list:
			if mode == 'Overview':
				self._mixer_modes.get_mode_button(mode).mode_selected_color = u'MainModes.SelectedOn'
				self._mixer_modes.get_mode_button(mode).mode_unselected_color = u'MainModes.SelectedOn'
			else:
				self._mixer_modes.get_mode_button(mode).mode_selected_color = u'SubModes.SelectedOn'
				self._mixer_modes.get_mode_button(mode).mode_unselected_color = u'SubModes.SelectedOff'
		self._mixer_modes.selected_mode = 'Overview'
		self._mixer_modes.layer = Layer(priority = 1, Overview_button = self._top_buttons[7], TrackVolume_button = self._side_buttons[0], TrackPan_button = self._side_buttons[1], TrackSend1_button = self._side_buttons[2], TrackSend2_button = self._side_buttons[3])
		self._mixer_modes.set_enabled(False)

		self._selector = ModesComponent(name = u'Selector')
		self._selector.add_mode(u'disabled', [self._background])
		self._selector.add_mode(u'Session', [self._session_modes])
		self._selector.add_mode(u'User1', [self._translations1])
		self._selector.add_mode(u'User2', [self._translations2])
		self._selector.add_mode(u'Mixer', [tuple([self.enable_sliders, self.disable_sliders]), self._mixer_modes])
		for mode in self._selector._mode_list:
			self._selector.get_mode_button(mode).mode_selected_color = u'MainModes.SelectedOn'
			self._selector.get_mode_button(mode).mode_unselected_color = u'MainModes.SelectedOff'
		self._selector.layer = Layer(priority = 1, Session_button = self._top_buttons[4], User1_button = self._top_buttons[5], User2_button = self._top_buttons[6], Mixer_button = self._top_buttons[7])
		self._selector.set_enabled(True)
		self._selector.selected_mode = u'disabled'

	def enable_sliders(self):
		for slider in self._sliders:
			slider._disabled = False
	

	def disable_sliders(self):
		for slider in self._sliders:
			slider._disabled = True
	

	def set_slider_single_mode(self):
		for slider in self._sliders:
			slider.set_mode(0)
	

	def set_slider_volume_mode(self):
		for slider in self._sliders:
			slider.set_mode(1)
	

	def set_slider_pan_mode(self):
		for slider in self._sliders:
			slider.set_mode(2)
	

	def set_slider_send_mode(self):
		for slider in self._sliders:
			slider.set_mode(1)
	

	def disconnect(self):
		self._suppress_send_midi = True
		for control in self.controls:
			if isinstance(control, ConfigurableButtonElement):
				control.remove_value_listener(self._button_value)

		self._selector = None
		self._user_byte_write_button.remove_value_listener(self._user_byte_value)
		self._config_button.remove_value_listener(self._config_value)
		super(Launchpad, self).disconnect()
		self._suppress_send_midi = False
		self._config_button.send_value(32)
		self._config_button.send_value(0)
		self._config_button = None
		self._user_byte_write_button.send_value(0)
		self._user_byte_write_button = None
	

	def refresh_state(self):
		super(Launchpad, self).refresh_state()
		self.schedule_message(5, self._update_hardware)
	

	def process_midi_bytes(self, midi_bytes, midi_processor):
		#def handle_sysex(self, midi_bytes):
		if len(midi_bytes) == 8:
			if midi_bytes[1:5] == (0, 32, 41, 6):
				response = long(midi_bytes[5])
				response += long(midi_bytes[6]) << 8
				if response == Live.Application.encrypt_challenge2(self._challenge):
					self._on_handshake_successful()
		else:
			super(Launchpad, self).process_midi_bytes(midi_bytes, midi_processor)
	

	def _on_handshake_successful(self):
		debug('Launchpad._on_handshake_successful')
		self._suppress_send_midi = False
		self.set_enabled(True)
		self._selector.selected_mode = 'Session'
		self._selector.set_enabled(True)
		debug(self._selector.selected_mode)
	
	"""
	def build_midi_map(self, midi_map_handle):
		ControlSurface.build_midi_map(self, midi_map_handle)
		#if self._selector.mode_index == 1:
		#	new_channel = self._selector.channel_for_current_mode()
		#	for note in DRUM_NOTES:
		#		self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel)
	"""
	"""
	def _send_midi(self, midi_bytes, optimized = None):
		sent_successfully = False
		if not self._suppress_send_midi:
			sent_successfully = ControlSurface._send_midi(self, midi_bytes, optimized=optimized)
		return sent_successfully
	"""

	def _update_hardware(self):
		self._suppress_send_midi = False
		self._wrote_user_byte = True
		self._user_byte_write_button.send_value(1)
		self._suppress_send_midi = True
		self.set_enabled(False)
		self._suppress_send_midi = False
		self._send_challenge()
	

	def _send_challenge(self):
		for index in range(4):
			challenge_byte = self._challenge >> 8 * index & 127
			self._send_midi((176, 17 + index, challenge_byte))
	

	def _user_byte_value(self, value):
		if not value in range(128):
			raise AssertionError
			enabled = self._wrote_user_byte or value == 1
			self._control_is_with_automap = not enabled
			self._suppress_send_midi = self._control_is_with_automap
			if not self._control_is_with_automap:
				for control in self.controls:
					if isinstance(control, ConfigurableButtonElement):
						control.set_force_next_value()

			#self._selector.set_mode(0)
			self._selector.selected_mode = u'Session'
			self.set_enabled(enabled)
			self._suppress_send_midi = False
		else:
			self._wrote_user_byte = False
	

	def _button_value(self, value):
		debug('_button_value', value, self._selector.selected_mode, self._selector.is_enabled())
		#self._top_buttons[0].send_value(127)
		#assert value in range(128)
	

	def _config_value(self, value):
		assert value in range(128)
	
	"""
class Push(PushBase):
    input_target_name_for_auto_arm = 'Push Input'
    device_component_class = DeviceComponent
    device_provider_class = DeviceProvider
    selected_track_parameter_provider_class = SelectedTrackParameterProvider
    bank_definitions = BANK_DEFINITIONS
    note_editor_class = NoteEditorComponent
    sliced_simpler_class = SlicedSimplerComponent
    quantization_settings_class = QuantizationSettingsComponent
    note_settings_component_class = NoteSettingsComponent
    automation_component_class = AutomationComponent

    def __init__(self, *a, **k):
        (super(Push, self).__init__)(*a, **k)
        with self.component_guard():
            self.initialize()
        logger.info('Push script loaded')
        self._send_midi(sysex.WELCOME_MESSAGE)

    def disconnect(self):
        super(Push, self).disconnect()
        logger.info('Push script unloaded')
        self._send_midi(sysex.GOOD_BYE_MESSAGE)

    def port_settings_changed(self):
        super(Push, self).port_settings_changed()
        self._start_handshake_task.restart()

    def on_select_clip_slot(self, clip_slot):
        self._selector.on_select_clip(clip_slot)

    def on_select_scene(self, scene):
        self._selector.on_select_scene(scene)

    def on_select_track(self, track):
        self._selector.on_select_track(track)

    def _create_components(self):
        self._init_handshake()
        self._init_selector()
        super(Push, self)._create_components()
        self._init_browser()
        self._init_track_modes()

    def _create_settings(self):
        settings = create_settings(preferences=(self.preferences))
        self._Push__on_pad_curve.subject = settings['curve']
        self._Push__on_pad_threshold.subject = settings['threshold']
        self._Push__on_aftertouch_threshold.subject = settings[
            'aftertouch_threshold']
        self._Push__on_aftertouch_mode.subject = settings['aftertouch_mode']
        return settings

    def _create_device_decorator_factory(self):
        return DeviceDecoratorFactory()

    def _init_settings(self):
        super(Push, self)._init_settings()
        self._init_global_pad_parameters()
        self._update_pad_params()

    def _init_selector(self):
        self._selector = SelectComponent(name='Selector')
        self._selector.layer = Layer(select_button='select_button')
        self._selector.selection_display_layer = Layer(
            display_line='display_line3', priority=(consts.DIALOG_PRIORITY))

    def _init_handshake(self):
        dongle_message, dongle = make_dongle_message(
            sysex.DONGLE_ENQUIRY_PREFIX)
        identity_control = create_sysex_element(sysex.IDENTITY_PREFIX,
                                                sysex.IDENTITY_ENQUIRY)
        dongle_control = create_sysex_element(sysex.DONGLE_PREFIX,
                                              dongle_message)
        presentation_control = create_sysex_element(
            sysex.DONGLE_PREFIX,
            sysex.make_presentation_message(self.application))
        self._handshake = HandshakeComponent(
            identity_control=identity_control,
            dongle_control=dongle_control,
            presentation_control=presentation_control,
            dongle=dongle)
        self._on_handshake_success.subject = self._handshake
        self._on_handshake_failure.subject = self._handshake
        self._start_handshake_task = self._tasks.add(
            task.sequence(task.wait(HANDSHAKE_DELAY),
                          task.run(self._start_handshake)))
        self._start_handshake_task.kill()

    def _init_user(self):
        super(Push, self)._init_user()
        self._on_push_hardware_mode_changed.subject = self._user
        self._update_pad_params()

    def _with_firmware_version(self, major_version, minor_version,
                               control_element):
        return MinimumFirmwareVersionElement(major_version, minor_version,
                                             control_element, self._handshake)

    def _start_handshake(self):
        self._start_handshake_task.kill()
        self.elements.playhead_element.proxied_object = self._c_instance.playhead
        self.elements.velocity_levels_element.proxied_object = self._c_instance.velocity_levels
        self.elements.full_velocity_element.proxied_object = self._c_instance.full_velocity
        self._note_repeat_enabler.set_note_repeat(self._c_instance.note_repeat)
        for control in self.controls:
            receive_value_backup = getattr(control, '_receive_value_backup',
                                           nop)
            if receive_value_backup != nop:
                control.receive_value = receive_value_backup
            send_midi_backup = getattr(control, '_send_midi_backup', nop)
            if send_midi_backup != nop:
                control.send_midi = send_midi_backup

        self._handshake._start_handshake()
        self.update()

    @listens('success')
    def _on_handshake_success(self):
        logger.info('Handshake succeded with firmware version %.2f!' %
                    self._handshake.firmware_version)
        self.update()
        self._c_instance.set_firmware_version(self._handshake.firmware_version)
        if self._handshake.has_version_requirements(1, 16):
            self._user.settings = self._settings
        else:
            settings = copy(self._settings)
            del settings['aftertouch_threshold']
            self._user.settings = settings
        self._Push__on_aftertouch_mode(self._settings['aftertouch_mode'].value)

    @listens('failure')
    def _on_handshake_failure(self, bootloader_mode):
        logger.error('Handshake failed, performing harakiri!')
        if bootloader_mode:
            self._c_instance.set_firmware_version(0.0)
        self._c_instance.playhead.enabled = False
        self.elements.playhead_element.proxied_object = NullPlayhead()
        self._c_instance.velocity_levels.enabled = False
        self.elements.velocity_levels_element.proxied_object = NullVelocityLevels(
        )
        self._c_instance.full_velocity.enabled = False
        self.elements.full_velocity_element.proxied_object = NullFullVelocity()
        self._note_repeat_enabler.set_note_repeat(None)
        for control in self.controls:
            receive_value_backup = getattr(control, 'receive_value', nop)
            send_midi_backup = getattr(control, 'send_midi', nop)
            try:
                control.receive_value = nop
                if receive_value_backup != nop:
                    control._receive_value_backup = receive_value_backup
                control.send_midi = nop
                if send_midi_backup != nop:
                    control._send_midi_backup = send_midi_backup
            except AttributeError:
                pass

    @listens('mode')
    def _on_push_hardware_mode_changed(self, mode):
        if mode == LIVE_MODE:
            if self._start_handshake_task.is_running:
                self._start_handshake()
            elif self._handshake.handshake_succeeded:
                self.update()

    def _create_background_layer(self):
        return super(Push, self)._create_background_layer() + Layer(
            display_line1='display_line1',
            display_line2='display_line2',
            display_line3='display_line3',
            display_line4='display_line4',
            in_button='in_button',
            out_button='out_button',
            pad_parameters=(self._pad_parameter_control))

    def _create_message_box_background_layer(self):
        return super(Push, self)._create_message_box_background_layer(
        ) + BackgroundLayer(
            'in_button', 'out_button', priority=(consts.MESSAGE_BOX_PRIORITY))

    def _create_track_frozen_layer(self):
        return Layer(display='display_line2',
                     _notification=(self._notification.use_full_display(1)))

    def _create_notification_component(self):
        return NotificationComponent(display_lines='display_lines',
                                     is_enabled=True)

    def _create_message_box_layer(self):
        return Layer(display_line1='display_line1',
                     display_line2='display_line2',
                     display_line3='display_line3',
                     display_line4='display_line4',
                     cancel_button='select_buttons_raw[-1]',
                     priority=(consts.MESSAGE_BOX_PRIORITY))

    def _create_clip_mode(self):
        return [self._track_modes, (self._mixer, self._mixer_layer)] + super(
            Push, self)._create_clip_mode()

    def _create_clip_loop_layer(self):
        return super(Push, self)._create_clip_loop_layer() + Layer(
            name_display=(self.elements.display_line1.subdisplay[:36]),
            value_display=(self.elements.display_line2.subdisplay[:36]))

    def _create_clip_audio_layer(self):
        return super(Push, self)._create_clip_audio_layer() + Layer(
            name_display=(self.elements.display_line1.subdisplay[36:]),
            value_display=(self.elements.display_line2.subdisplay[36:]))

    def _create_clip_name_layer(self):
        return super(Push, self)._create_clip_name_layer() + Layer(
            display='display_line3')

    def _init_track_modes(self):
        self._track_modes = ModesComponent(name='Track_Modes')
        self._track_modes.set_enabled(False)
        self._track_modes.add_mode(
            'stop', AddLayerMode(self._stop_clips,
                                 self._stop_track_clips_layer))
        self._track_modes.add_mode(
            'solo', AddLayerMode(self._mixer, self._mixer_solo_layer))
        self._track_modes.add_mode(
            'mute', AddLayerMode(self._mixer, self._mixer_mute_layer))
        self._track_modes.layer = self._create_track_modes_layer()
        self._track_modes.selected_mode = 'mute'

    def _browser_back_to_top(self):
        self._browser_mode.component.back_to_top()

    def _browser_reset_load_memory(self):
        self._browser_mode.component.reset_load_memory()

    def _init_browser(self):
        self._browser_mode = BrowserMode(self._create_browser,
                                         self._scales_enabler)
        self._browser_hotswap_mode = MultiEntryMode(
            BrowserHotswapMode(application=(self.application)))
        self._on_browse_mode_changed.subject = self.application.view

    def _create_main_mixer_modes(self):
        self._main_modes.add_mode('volumes', [
            self._track_modes, (self._mixer, self._mixer_volume_layer),
            self._track_note_editor_mode
        ])
        self._main_modes.add_mode('pan_sends', [
            self._track_modes, (self._mixer, self._mixer_pan_send_layer),
            self._track_note_editor_mode
        ])
        self._main_modes.add_mode('track', [
            self._track_modes, self._track_mixer,
            (self._mixer, self._mixer_track_layer),
            self._track_note_editor_mode
        ])

    def _init_browse_mode(self):
        self._main_modes.add_mode(
            'browse', [
                self._when_track_is_not_frozen(
                    self._enable_stop_mute_solo_as_modifiers,
                    partial(self._view_control.show_view, 'Browser'),
                    self._browser_back_to_top, self._browser_hotswap_mode,
                    self._browser_mode, self._browser_reset_load_memory)
            ],
            groups=['add_effect', 'add_track', 'browse'],
            behaviour=(mixin(DynamicBehaviourMixin, CancellableBehaviour)(
                lambda: not self._browser_hotswap_mode._mode.can_hotswap(
                ) and 'add_effect_left')))
        self._main_modes.add_mode(
            'add_effect_right', [
                self._when_track_is_not_frozen(
                    self._enable_stop_mute_solo_as_modifiers,
                    self._browser_back_to_top,
                    LazyEnablingMode(self._create_create_device_right))
            ],
            behaviour=(mixin(ExcludingBehaviourMixin,
                             CancellableBehaviour)(['add_track', 'browse'])),
            groups=['add_effect'])
        self._main_modes.add_mode(
            'add_effect_left', [
                self._when_track_is_not_frozen(
                    self._enable_stop_mute_solo_as_modifiers,
                    self._browser_back_to_top,
                    LazyEnablingMode(self._create_create_device_left))
            ],
            behaviour=(mixin(ExcludingBehaviourMixin,
                             CancellableBehaviour)(['add_track', 'browse'])),
            groups=['add_effect'])
        self._main_modes.add_mode(
            'add_instrument_track', [
                self._enable_stop_mute_solo_as_modifiers,
                self._browser_back_to_top,
                LazyEnablingMode(self._create_create_instrument_track)
            ],
            behaviour=mixin(ExcludingBehaviourMixin, AlternativeBehaviour)(
                excluded_groups=['browse', 'add_effect'],
                alternative_mode='add_default_track'),
            groups=['add_track'])
        self._main_modes.add_mode('add_default_track', [
            self._enable_stop_mute_solo_as_modifiers,
            self._browser_back_to_top,
            LazyEnablingMode(self._create_create_default_track)
        ],
                                  groups=['add_track'])
        self._main_modes.add_effect_right_button.mode_unselected_color = self._main_modes.add_effect_left_button.mode_unselected_color = self._main_modes.add_instrument_track_button.mode_unselected_color = 'DefaultButton.On'

    @listens('browse_mode')
    def _on_browse_mode_changed(self):
        if self.application.browser.hotswap_target or (
                self._main_modes.selected_mode == 'browse'
                or self._browser_hotswap_mode.is_entered):
            self._main_modes.selected_mode = 'device'

    def _create_browser(self):
        state_buttons = self.elements.track_state_buttons.submatrix[:7, :]
        browser = BrowserComponent(
            name='Browser',
            is_enabled=False,
            layer=Layer(
                encoder_controls='global_param_controls',
                display_line1='display_line1',
                display_line2='display_line2',
                display_line3='display_line3',
                display_line4='display_line4',
                enter_button='in_button',
                exit_button='out_button',
                select_buttons='select_buttons',
                state_buttons=state_buttons,
                shift_button=(WithPriority(consts.SHARED_PRIORITY,
                                           'shift_button')),
                prehear_button='track_state_buttons_raw[7]',
                _notification=(self._notification.use_full_display(2))),
            make_browser_model=make_browser_model,
            preferences=(self.preferences))
        return browser

    def _create_create_device_right(self):
        return CreateDeviceComponent(
            name='Create_Device_Right',
            browser_component=(self._browser_mode.component),
            browser_mode=(self._browser_mode),
            browser_hotswap_mode=(self._browser_hotswap_mode),
            insert_left=False,
            is_enabled=False)

    def _create_create_device_left(self):
        return CreateDeviceComponent(
            name='Create_Device_Right',
            browser_component=(self._browser_mode.component),
            browser_mode=(self._browser_mode),
            browser_hotswap_mode=(self._browser_hotswap_mode),
            insert_left=True,
            is_enabled=False)

    def _create_create_default_track(self):
        create_default_track = CreateDefaultTrackComponent(
            name='Create_Default_Track', is_enabled=False)
        create_default_track.options.layer = Layer(
            display_line='display_line4',
            label_display_line='display_line3',
            blank_display_line2='display_line2',
            blank_display_line1='display_line1',
            select_buttons='select_buttons',
            state_buttons='track_state_buttons',
            priority=(consts.DIALOG_PRIORITY))
        return create_default_track

    def _create_create_instrument_track(self):
        return CreateInstrumentTrackComponent(
            name='Create_Instrument_Track',
            browser_component=(self._browser_mode.component),
            browser_mode=(self._browser_mode),
            browser_hotswap_mode=(self._browser_hotswap_mode),
            is_enabled=False)

    def _create_device_mode(self):
        return [
            self._when_track_is_not_frozen(
                self._enable_stop_mute_solo_as_modifiers,
                partial(self._view_control.show_view, 'Detail/DeviceChain'),
                self._device_parameter_component, self._device_navigation,
                self._device_note_editor_mode)
        ]

    def _create_scales(self):
        scales = InstrumentScalesComponent(
            note_layout=(self._note_layout),
            is_enabled=False,
            name='Scales',
            layer=(
                BackgroundLayer('display_line1',
                                'display_line2',
                                priority=(consts.DIALOG_PRIORITY)),
                Layer(
                    scale_line1=(self.elements.display_line1.subdisplay[:18]),
                    scale_line2=(self.elements.display_line2.subdisplay[:18]),
                    scale_line3=(self.elements.display_line3.subdisplay[:9]),
                    scale_line4=(self.elements.display_line4.subdisplay[:9]),
                    top_display_line=(
                        self.elements.display_line3.subdisplay[9:]),
                    bottom_display_line=(
                        self.elements.display_line4.subdisplay[9:]),
                    top_buttons='select_buttons',
                    bottom_buttons='track_state_buttons',
                    encoder_controls='global_param_controls',
                    _notification=(self._notification.use_single_line(
                        0, get_slice[18:], align_right)),
                    priority=(consts.DIALOG_PRIORITY)),
                Layer(presets_toggle_button='shift_button')))
        scales.presets_layer = (
            BackgroundLayer('track_state_buttons',
                            'global_param_controls',
                            'display_line1',
                            'display_line2',
                            priority=(consts.DIALOG_PRIORITY)),
            Layer(top_display_line='display_line3',
                  bottom_display_line='display_line4',
                  top_buttons='select_buttons',
                  _notification=(self._notification.use_single_line(0)),
                  priority=(consts.DIALOG_PRIORITY)))
        return scales

    def _create_scales_enabler(self):
        return EnablingModesComponent(
            component=(self._create_scales()),
            enabled_color='DefaultButton.On',
            is_enabled=False,
            layer=Layer(cycle_mode_button='scale_presets_button'))

    def _create_drum_component(self):
        return DrumGroupComponent(name='Drum_Group',
                                  is_enabled=False,
                                  quantizer=(self._quantize),
                                  selector=(self._selector))

    def _create_note_settings_component_layer(self):
        return Layer(top_display_line='display_line1',
                     bottom_display_line='display_line2',
                     info_display_line='display_line3',
                     clear_display_line='display_line4',
                     full_velocity_button='accent_button',
                     priority=(consts.MOMENTARY_DIALOG_PRIORITY))

    def _create_note_editor_track_automation_layer(self):
        return super(
            Push, self)._create_note_editor_track_automation_layer() + Layer(
                name_display_line='display_line1',
                graphic_display_line='display_line2',
                value_display_line='display_line3',
                priority=(consts.MOMENTARY_DIALOG_PRIORITY))

    def _create_note_editor_device_automation_layer(self):
        return super(
            Push, self)._create_note_editor_device_automation_layer() + Layer(
                name_display_line='display_line1',
                value_display_line='display_line2',
                graphic_display_line='display_line3',
                priority=(consts.MOMENTARY_DIALOG_PRIORITY))

    def _init_stop_clips_action(self):
        self._stop_clips = StopClipComponent(session_ring=(self._session_ring),
                                             name='Stop_Clip')
        self._stop_clips.layer = Layer(stop_all_clips_button=(
            self._with_shift('global_track_stop_button')))
        self._stop_track_clips_layer = Layer(
            stop_track_clips_buttons='track_state_buttons')

    def _init_quantize_actions(self):
        self._quantize = self._for_non_frozen_tracks(
            QuantizationComponent(
                name='Selected_Clip_Quantize',
                settings_class=(self.quantization_settings_class),
                is_enabled=False,
                layer=Layer(action_button='quantize_button')))
        self._quantize.settings.layer = (
            BackgroundLayer('global_param_controls',
                            'select_buttons',
                            'track_state_buttons',
                            priority=(consts.MOMENTARY_DIALOG_PRIORITY)),
            Layer(
                swing_amount_encoder='parameter_controls_raw[0]',
                quantize_to_encoder='parameter_controls_raw[1]',
                quantize_amount_encoder='parameter_controls_raw[2]',
                record_quantization_encoder='parameter_controls_raw[7]',
                record_quantization_toggle_button='track_state_buttons_raw[7]',
                display_line1='display_line1',
                display_line2='display_line2',
                display_line3='display_line3',
                display_line4='display_line4',
                priority=(consts.MOMENTARY_DIALOG_PRIORITY)))

    def _init_fixed_length(self):
        super(Push, self)._init_fixed_length()
        self._fixed_length.settings_component.layer = (
            BackgroundLayer(
                (self.elements.track_state_buttons.submatrix[:7, :]),
                'display_line1',
                'display_line2',
                priority=(consts.MOMENTARY_DIALOG_PRIORITY)),
            Layer(length_option_buttons='select_buttons',
                  label_display_line='display_line3',
                  option_display_line='display_line4',
                  legato_launch_toggle_button='track_state_buttons_raw[7]',
                  _notification=(self._notification.use_single_line(1)),
                  priority=(consts.MOMENTARY_DIALOG_PRIORITY)))

    def _create_note_repeat_layer(self):
        return super(Push, self)._create_note_repeat_layer() + Layer(
            pad_parameters=(self._pad_parameter_control),
            priority=(consts.DIALOG_PRIORITY))

    def _create_user_component(self):
        sysex_control = create_sysex_element(sysex.MODE_CHANGE)
        user = UserComponent(value_control=sysex_control)
        user.layer = Layer(action_button='user_button')
        user.settings_layer = Layer(display_line1='display_line1',
                                    display_line2='display_line2',
                                    display_line3='display_line3',
                                    display_line4='display_line4',
                                    encoders='global_param_controls')
        user.settings_layer.priority = consts.DIALOG_PRIORITY
        return user

    def _init_value_components(self):
        super(Push, self)._init_value_components()
        self._swing_amount.display.layer = (
            BackgroundLayer('display_line4',
                            priority=(consts.DIALOG_PRIORITY)),
            Layer(label_display='display_line1',
                  value_display='display_line3',
                  graphic_display='display_line2',
                  priority=(consts.DIALOG_PRIORITY)))
        self._tempo.display.layer = (BackgroundLayer(
            'display_line3',
            'display_line4',
            priority=(consts.DIALOG_PRIORITY)),
                                     Layer(label_display='display_line1',
                                           value_display='display_line2',
                                           priority=(consts.DIALOG_PRIORITY)))
        self._master_vol.display.layer = (
            BackgroundLayer('display_line4',
                            priority=(consts.DIALOG_PRIORITY)),
            Layer(label_display='display_line1',
                  value_display='display_line3',
                  graphic_display='display_line2',
                  priority=(consts.DIALOG_PRIORITY)))
        self._master_cue_vol.display.layer = (
            BackgroundLayer('display_line4',
                            priority=(consts.DIALOG_PRIORITY)),
            Layer(label_display='display_line1',
                  value_display='display_line3',
                  graphic_display='display_line2',
                  priority=(consts.DIALOG_PRIORITY)))

    def _create_note_mode(self):
        return super(Push, self)._create_note_mode() + [
            self._percussion_instrument_finder, self._global_pad_parameters
        ]

    def _instantiate_session(self):
        return SpecialSessionComponent(
            session_ring=(self._session_ring),
            is_enabled=False,
            auto_name=True,
            fixed_length_recording=(self._create_fixed_length_recording()),
            layer=(self._create_session_layer()))

    def _create_session_mode(self):
        return [
            self._session_overview_mode, self._session_mode,
            self._session_navigation
        ]

    def _create_session_overview_layer(self):
        return Layer(button_matrix='shifted_matrix')

    def _set_session_skin(self, session):
        session.set_rgb_mode(LIVE_COLORS_TO_MIDI_VALUES,
                             RGB_COLOR_TABLE,
                             clip_slots_only=True)

    def _on_selected_track_changed(self):
        super(Push, self)._on_selected_track_changed()
        self._main_modes.pop_groups(['add_effect'])

    def _init_main_modes(self):
        super(Push, self)._init_main_modes()
        self._Push__on_main_mode_button_value.replace_subjects([
            self.elements.vol_mix_mode_button,
            self.elements.pan_send_mix_mode_button,
            self.elements.single_track_mix_mode_button,
            self.elements.clip_mode_button, self.elements.device_mode_button,
            self.elements.browse_mode_button
        ])

    def _create_mixer_layer(self):
        return Layer(track_select_buttons='select_buttons',
                     track_names_display='display_line4')

    def _create_mixer_solo_layer(self):
        return Layer(solo_buttons='track_state_buttons')

    def _create_mixer_mute_layer(self):
        return Layer(mute_buttons='track_state_buttons')

    def _create_mixer_pan_send_layer(self):
        return Layer(track_select_buttons='select_buttons',
                     pan_send_toggle='pan_send_mix_mode_button',
                     pan_send_controls='fine_grain_param_controls',
                     track_names_display='display_line4',
                     pan_send_names_display='display_line1',
                     pan_send_graphics_display='display_line2',
                     selected_track_name_display='display_line3',
                     pan_send_values_display=(ComboElement(
                         'display_line3', 'any_touch_button')))

    def _create_mixer_volume_layer(self):
        return Layer(track_select_buttons='select_buttons',
                     volume_controls='fine_grain_param_controls',
                     track_names_display='display_line4',
                     volume_names_display='display_line1',
                     volume_graphics_display='display_line2',
                     selected_track_name_display='display_line3',
                     volume_values_display=(ComboElement(
                         'display_line3', 'any_touch_button')))

    def _create_mixer_track_layer(self):
        return Layer(track_select_buttons='select_buttons',
                     selected_track_name_display='display_line3',
                     track_names_display='display_line4')

    def _init_mixer(self):
        self._mixer = SpecialMixerComponent(
            tracks_provider=(self._session_ring))
        self._mixer.set_enabled(False)
        self._mixer.name = 'Mixer'
        self._mixer_layer = self._create_mixer_layer()
        self._mixer_pan_send_layer = self._create_mixer_pan_send_layer()
        self._mixer_volume_layer = self._create_mixer_volume_layer()
        self._mixer_track_layer = self._create_mixer_track_layer()
        self._mixer_solo_layer = self._create_mixer_solo_layer()
        self._mixer_mute_layer = self._create_mixer_mute_layer()
        for track in range(self.elements.matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            strip.set_invert_mute_feedback(True)
            strip.set_delete_handler(self._delete_component)
            strip._do_select_track = self.on_select_track
            strip.layer = Layer(shift_button='shift_button',
                                duplicate_button='duplicate_button',
                                selector_button='select_button')

        self._mixer.selected_strip().name = 'Selected_Channel_strip'
        self._mixer.master_strip().name = 'Master_Channel_strip'
        self._mixer.master_strip()._do_select_track = self.on_select_track
        self._mixer.master_strip().layer = Layer(
            select_button='master_select_button',
            selector_button='select_button')
        self._mixer.set_enabled(True)

    def _create_track_mixer_layer(self):
        return super(Push, self)._create_track_mixer_layer() + Layer(
            name_display_line='display_line1',
            graphic_display_line='display_line2',
            value_display_line=(ComboElement('display_line3',
                                             'any_touch_button')))

    def _create_device_parameter_layer(self):
        return super(Push, self)._create_device_parameter_layer() + Layer(
            name_display_line='display_line1',
            value_display_line='display_line2',
            graphic_display_line=(ComboElement('display_line3',
                                               'any_touch_button')))

    def _create_device_navigation(self):
        return DeviceNavigationComponent(
            device_bank_registry=(self._device_bank_registry),
            banking_info=(self._banking_info),
            is_enabled=False,
            session_ring=(self._session_ring),
            layer=Layer(enter_button='in_button',
                        exit_button='out_button',
                        select_buttons='select_buttons',
                        state_buttons='track_state_buttons',
                        display_line='display_line4',
                        _notification=(self._notification.use_single_line(2))),
            info_layer=Layer(
                display_line1='display_line1',
                display_line2='display_line2',
                display_line3='display_line3',
                display_line4='display_line4',
                _notification=(self._notification.use_full_display(2))),
            delete_handler=(self._delete_component))

    def _init_device(self):
        super(Push, self)._init_device()
        self._device_component.layer = Layer(shift_button='shift_button')

    @listens_group('value')
    def __on_main_mode_button_value(self, value, sender):
        if not value:
            self._scales_enabler.selected_mode = 'disabled'

    def _create_controls(self):
        self._create_pad_sensitivity_update()
        push_ref = weakref.ref(self)

        class Deleter(object):
            @property
            def is_deleting(_):
                if push_ref():
                    return push_ref()._delete_default_component.is_deleting
                raise RuntimeError(
                    'Attempting to check if Push is deleting when the Push instance is dead'
                )

            def delete_clip_envelope(_, param):
                if push_ref():
                    return push_ref(
                    )._delete_default_component.delete_clip_envelope(param)
                raise RuntimeError(
                    'Attempting to delete clip envelope when Push instance is dead'
                )

        self.elements = Elements(
            deleter=(Deleter()),
            undo_handler=UndoStepHandler(song=(self.song)),
            pad_sensitivity_update=(self._pad_sensitivity_update),
            playhead=(self._c_instance.playhead),
            velocity_levels=(self._c_instance.velocity_levels),
            full_velocity=(self._c_instance.full_velocity))

    def _create_pad_sensitivity_update(self):
        all_pad_sysex_control = create_sysex_element(
            sysex.ALL_PADS_SENSITIVITY_PREFIX)
        pad_sysex_control = create_sysex_element(sysex.PAD_SENSITIVITY_PREFIX)
        sensitivity_sender = pad_parameter_sender(all_pad_sysex_control,
                                                  pad_sysex_control)
        self._pad_sensitivity_update = PadUpdateComponent(
            all_pads=(list(range(64))),
            parameter_sender=sensitivity_sender,
            default_profile=action_pad_sensitivity,
            update_delay=TIMER_DELAY)

    def _init_global_pad_parameters(self):
        self._pad_parameter_control = self._with_firmware_version(
            1, 16,
            create_sysex_element(
                (sysex.PAD_PARAMETER_PREFIX),
                default_value=(sysex.make_pad_parameter_message())))
        aftertouch_threshold = self._settings['aftertouch_threshold'].value
        self._global_pad_parameters = GlobalPadParameters(
            aftertouch_threshold=aftertouch_threshold,
            is_enabled=False,
            layer=Layer(pad_parameter=(self._pad_parameter_control)))

    @listens('value')
    def __on_pad_curve(self, _value):
        self._update_pad_params()

    @listens('value')
    def __on_pad_threshold(self, value):
        self._user.set_settings_info_text(
            '' if value >= CRITICAL_THRESHOLD_LIMIT else consts.MessageBoxText.
            STUCK_PAD_WARNING)
        self._update_pad_params()

    @listens('value')
    def __on_aftertouch_threshold(self, value):
        self._global_pad_parameters.aftertouch_threshold = value

    @listens('value')
    def __on_aftertouch_mode(self, value):
        mode = 'mono' if value else 'polyphonic'
        self._instrument.instrument.set_aftertouch_mode(mode)
        self._selected_note_instrument.set_aftertouch_mode(mode)

    def _update_pad_params(self):
        new_pad_parameters = make_pad_parameters(
            self._settings['curve'].value, self._settings['threshold'].value)
        self._pad_sensitivity_update.set_profile('instrument',
                                                 new_pad_parameters)
        self._pad_sensitivity_update.set_profile('drums', new_pad_parameters)
        self._pad_sensitivity_update.set_profile('loop',
                                                 action_pad_sensitivity)

    def _update_calibration(self):
        self._send_midi(sysex.CALIBRATION_SET)

    def update(self):
        self._update_calibration()
        super(Push, self).update()
Example #15
0
class Twister(LividControlSurface):
	__module__ = __name__
	__doc__ = " Monomodular controller script for Livid CNTRLR "


	_sysex_id = 8
	_model_name = 'Twister'
	_host_name = 'Twister'
	_version_check = 'b996'
	monomodular = None

	device_provider_class = ModDeviceProvider

	def __init__(self, *a, **k):
		super(Twister, self).__init__(*a, **k)
		self._skin = Skin(TwisterColors)
		self._device_selection_follows_track_selection = True
		with self.component_guard():
			self._setup_monobridge()
			self._setup_controls()
			#self._define_sysex()
			self._setup_background()
			self._setup_m4l_interface()
			self._setup_mod()
			self._setup_device_control()
			self._setup_modes()
		self._on_device_changed.subject = self.song
		self._on_selected_track_changed.subject = self.song.view
	

	def _initialize_script(self):
		super(Twister, self)._initialize_script()
		self._connected = True
	

	def _setup_controls(self):
		is_momentary = True
		optimized = True
		resource = PrioritizedResource
		self._encoder = [CodecEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = TWISTER_DIALS[index], name = 'Encoder_' + str(index), num = TWISTER_DIALS[index], script = self, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(16)] 
		self._encoder_button = [TwisterButtonElement(is_momentary = is_momentary, msg_type = MIDI_CC_TYPE, channel = 1, identifier = TWISTER_DIAL_BUTTONS[index], name = 'Encoder_Button_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(16)]	

		self._dial_matrix = ButtonMatrixElement(name = 'Dial_Matrix', rows = [self._encoder[index*4:(index*4)+4] for index in range(4)])
		self._dial_button_matrix = ButtonMatrixElement(name = 'Dial_Button_Matrix', rows = [self._encoder_button[index*4:(index*4)+4] for index in range(4)])
	

	def _setup_background(self):
		self._background = BackgroundComponent(name = 'Background')
		self._background.layer = Layer(priority = 3, dials = self._dial_matrix, dial_buttons = self._dial_button_matrix.submatrix[:,:])
		self._background.set_enabled(True)
	

	def _setup_m4l_interface(self):
		self._m4l_interface = M4LInterfaceComponent(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 _define_sysex(self):
		pass
	

	def _check_connection(self):
		self._connected = True
		self._initialize_hardware()
		self._initialize_script()
	

	def _setup_mixer_control(self):
		self._mixer_session_ring = SessionRingComponent(num_tracks = 4, num_scenes = 4)
		self._mixer = MonoMixerComponent(name = 'Mixer', tracks_provider = self._mixer_session_ring, track_assigner = simple_track_assigner, invert_mute_feedback = True, auto_name = True, enable_skinning = True)

		self._mixer.layer = Layer(priority = 4, 
											solo_buttons = self._dial_button_matrix.submatrix[:,0],
											stop_clip_buttons = self._dial_button_matrix.submatrix[:,1],
											track_select_buttons = self._dial_button_matrix.submatrix[:,2])
		self._mixer.set_enabled(True)
	

	def _setup_device_control(self):
		self._device = SpecialDeviceComponent(name = 'Device_Component', device_provider = self._device_provider, device_bank_registry = DeviceBankRegistry(), script = self)
		self._device.layer = Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:,:],)
		self._device.bank_layer = AddLayerMode(self._device, Layer(priority = 4, 
												bank_prev_button = self._encoder_button[12],
												bank_next_button = self._encoder_button[13]))
		self._device.set_enabled(False)
	

	def _setup_mod(self):
		self.monomodular = get_monomodular(self)
		self.monomodular.name = 'monomodular_switcher'
		self.modhandler = TwisterModHandler(self, device_provider = self._device_provider)
		self.modhandler.name = 'ModHandler' 
		self.modhandler.layer = Layer(priority = 8,
										twister_encoder_button_grid = self._dial_button_matrix.submatrix[:,:],)
										#twister_encoder_grid = self._dial_matrix.submatrix[:,:],)
		self.modhandler.set_enabled(False)
	

	def _setup_modes(self):
		self._modswitcher = ModesComponent(name = 'ModSwitcher')
		self._modswitcher.add_mode('mod', [self.modhandler, self._device])
		self._modswitcher.add_mode('device', [self._device, self._device.bank_layer])
		self._modswitcher.selected_mode = 'device'
		self._modswitcher.set_enabled(True)
	

	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 = 'device'
	

	@listens('appointed_device')
	def _on_device_changed(self):
		debug('appointed device changed, script')
		self._update_modswitcher()
	

	@listens('selected_track')
	def _on_selected_track_changed(self):
		debug('_on_selected_track_changed')
		#super(Cntrlr, self)._on_selected_track_changed()
		#self._drum_group_finder.device_parent = self.song.veiw.selected_track
		if not len(self.song.view.selected_track.devices):
			self._update_modswitcher()
	

	def restart_monomodular(self):
		#debug('restart monomodular')
		self.modhandler.disconnect()
		with self.component_guard():
			self._setup_mod()
Example #16
0
class Cntrlr(LividControlSurface):
	__module__ = __name__
	__doc__ = " Monomodular controller script for Livid CNTRLR "


	_sysex_id = 8
	_model_name = 'Cntrlr'
	_host_name = 'Cntrlr'
	monomodular = None

	device_provider_class = ModDeviceProvider

	def __init__(self, *a, **k):
		super(Cntrlr, self).__init__(*a, **k)
		self._skin = Skin(CntrlrColors)
		self._device_selection_follows_track_selection = FOLLOW
		with self.component_guard():
			self._setup_controls()
			self._define_sysex()
			self._setup_background()
			#self._setup_autoarm()
			self._setup_viewcontrol()
			self._setup_session_control()
			self._setup_mixer_control()
			self._setup_transport_control()
			#self._setup_device_control()
			#self._setup_device_selector()
			#self._setup_session_recording_component()
			#self._setup_modes()
			self._setup_m4l_interface()
	

	def _initialize_script(self):
		super(Cntrlr, self)._initialize_script()
		self._connected = True
		#self._main_modes.selected_mode = 'MixMode'

		self._session_ring._update_highlight()
		self._session_ring.track_offset = 0
		if liveobj_valid(self.song.visible_tracks[0]):
			self.song.view.selected_track = self.song.visible_tracks[0]
	

	def _setup_controls(self):
		is_momentary = True
		optimized = True
		resource = PrioritizedResource
		self._fader = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_FADERS[index], name = 'Fader_' + str(index), num = index, script = self,  optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(8)]
		self._dial_left = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_KNOBS_LEFT[index], name = 'Dial_Left_' + str(index), num = CNTRLR_KNOBS_LEFT[index], script = self, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)]
		self._dial_right = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_KNOBS_RIGHT[index], name = 'Dial_Right_' + str(index), num = CNTRLR_KNOBS_RIGHT[index], script = self, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)]
		self._encoder = [CodecEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_DIALS[index], name = 'Encoder_' + str(index), num = CNTRLR_DIALS[index], script = self, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)] 
		self._encoder_button = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CNTRLR_DIAL_BUTTONS[index], name = 'Encoder_Button_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)]	
		self._grid = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CNTRLR_GRID[index], name = 'Grid_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(16)]
		self._button = [MonoButtonElement(is_momentary = is_momentary,msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CNTRLR_BUTTONS[index], name = 'Button_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) 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 _setup_background(self):
		self._background = BackgroundComponent(name = 'Background')
		self._background.layer = Layer(priority = 3, matrix = self._matrix.submatrix[:,:], faders = self._fader_matrix.submatrix[:,:], left_knobs = self._knob_left_matrix.submatrix[:,:], right_knobs = self._knob_right_matrix.submatrix[:,:], dials = self._dial_matrix, dial_buttons = self._dial_button_matrix.submatrix[:,:], keys = self._key_matrix.submatrix[:,:])
		self._background.set_enabled(True)
	

	def _define_sysex(self):
		#self.encoder_navigation_on = SendLividSysexMode(livid_settings = self._livid_settings, call = 'set_encoder_encosion_mode', message = [13, 0, 0, 0]) 
		pass
	

	def _setup_transport_control(self):
		self._transport = CntrlrTransportComponent(name = 'Transport') 
		self._transport._play_toggle.view_transform = lambda value: 'Transport.PlayOn' if value else 'Transport.PlayOff'
		self._transport._record_toggle.view_transform = lambda value: 'Transport.RecordOn' if value else 'Transport.RecordOff'
		self._transport._nudge_up_toggle.view_transform = lambda value: 'Transport.NudgeOn' if value else 'Transport.NudgeOff'
		self._transport._nudge_down_toggle.view_transform = lambda value: 'Transport.NudgeOn' if value else 'Transport.NudgeOff'
		self._transport._loop_toggle.view_transform = lambda value: 'Transport.LoopOn' if value else 'Transport.LoopOff'
		self._transport.layer = Layer(priority = 4,
									play_button = self._button[28],
									stop_button = self._button[29],
									record_button = self._button[30],
									tap_tempo_button = self._button[31],
									nudge_up_button = self._button[3],
									nudge_down_button = self._button[19],
									loop_button = self._button[23])
		self._transport.set_enabled(True)
	

	def _setup_autoarm(self):
		self._auto_arm = CntrlrAutoArmComponent(name='Auto_Arm')
		#self._auto_arm._update_notification = lambda a: None
		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 = FixedLengthSessionRecordingComponent(clip_creator = self._clip_creator, view_controller = ViewControlComponent(), name = 'SessionRecorder') # is_enabled = False)
		self._recorder.main_layer = AddLayerMode(self._recorder, Layer(priority = 4, record_button = self._button[29]))
		#self._recorder.shift_layer = AddLayerMode(self._recorder, Layer(priority = 4, automation_button = self._button[29]))
		self._recorder.set_enabled(False)
	

	def _setup_session_control(self):
		self._session_ring = SessionRingComponent(num_tracks = 4, num_scenes = 4)
		self._session_ring.set_enabled(True)

		self._session_navigation = SessionNavigationComponent(name = 'SessionNavigation', session_ring = self._session_ring)

		self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_up_button.disabled_color = 'Session.PageNavigationButtonOff'
		self._session_navigation._vertical_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_down_button.disabled_color = 'Session.PageNavigationButtonOff'
		self._session_navigation._horizontal_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_up_button.disabled_color = 'Session.PageNavigationButtonOff'
		self._session_navigation._horizontal_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_down_button.disabled_color = 'Session.PageNavigationButtonOff'

		self._session_navigation.layer = Layer(priority = 4,
									down_button = self._button[14],
									up_button = self._button[15],
									left_button = self._button[12],
									right_button = self._button[13])
		self._session_navigation.set_enabled(True)

		self._session = SessionComponent(session_ring = self._session_ring, auto_name = True)
		hasattr(self._session, '_enable_skinning') and self._session._enable_skinning()
		self._session.layer = Layer(priority = 4,
									clip_launch_buttons = self._matrix.submatrix[:,:])
		self._session.set_enabled(True)
	

	def _setup_mixer_control(self):
		self._mixer_session_ring = SessionRingComponent(num_tracks = 4, num_scenes = 4)
		self._mixer = MonoMixerComponent(name = 'Mixer', tracks_provider = self._mixer_session_ring, track_assigner = simple_track_assigner, invert_mute_feedback = True, auto_name = True, enable_skinning = True)

		self._mixer.layer = Layer(priority = 4, 
											solo_buttons = self._key_matrix.submatrix[8:11, 0],
											stop_clip_buttons = self._key_matrix.submatrix[:3, 0],
											track_select_buttons = self._key_matrix.submatrix[4:8, 0],)
		for strip in self._mixer._channel_strips:
			strip._on_select_button_double_clicked = self._toggle_view
		self._mixer.set_enabled(True)
	

	def _toggle_view(self, *a):
		debug('toggle_view')
		debug('Clip is visible:', self.application().view.is_view_visible('Detail/Clip'))
		debug('Device is visible:', self.application().view.is_view_visible('Detail/DeviceChain'))
		if self.application().view.is_view_visible('Detail/Clip'):
			self._view_control.show_view('Detail/DeviceChain')
		else:
			self._view_control.show_view('Detail/Clip')

	def _setup_device_control(self):
		self._device_selection_follows_track_selection = FOLLOW
		self._device = DeviceComponent(name = 'Device_Component', device_provider = self._device_provider, device_bank_registry = DeviceBankRegistry())
		self._device.layer = Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:, 1:3],)
		#self._device.mod_layer = AddLayerMode(self._device, Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:, 1:3],))
		self._device.main_layer = AddLayerMode(self._device, Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:, 1:3], 
												on_off_button = self._encoder_button[4],
												bank_prev_button = self._encoder_button[6],
												bank_next_button = self._encoder_button[7],))
												#lock_button = self._encoder_button[5],
		self._device.set_enabled(False)

		self._device_navigator = DeviceNavigator(self._device_provider, self._mixer, self)
		self._device_navigator.name = 'Device_Navigator'
		self._device_navigator.select_dial_layer = AddLayerMode(self._device_navigator, Layer(priority = 6, device_select_dial = self._encoder[0],))
		self._device_navigator.main_layer = AddLayerMode(self._device_navigator, Layer(priority = 4, 
											prev_chain_button = self._encoder_button[8], 
											next_chain_button = self._encoder_button[9], 
											exit_button = self._encoder_button[10], 
											enter_button = self._encoder_button[11],))
		self._device_navigator.set_enabled(False)
	

	def _setup_device_selector(self):
		self._device_selector = DeviceSelectorComponent(self)
		self._device_selector.name = 'Device_Selector'
		#self._device_selector.select_layer = AddLayerMode(self._device_selector, Layer(priority = 6 , matrix = self._matrix.submatrix[:, :]))
		self._device_selector.select_layer = AddLayerMode(self._device_selector, Layer(priority = 6, matrix = ButtonMatrixElement(rows = [self._grid[:4],self._grid[4:8],self._grid[8:12],self._grid[12:14]])))
		self._device_selector.assign_layer = AddLayerMode(self._device_selector, Layer(priority = 7, assign_button = self._grid[14]))
		self._device_selector.set_enabled(False)
	

	def _setup_viewcontrol(self):
		self._view_control = ViewControlComponent(name='View_Control')
		#self._view_control.main_layer = AddLayerMode(self._view_control, Layer(priority = 5, 
		#																		scene_select_dial = self._encoder[2],
		#																		track_select_dial = self._encoder[3],))
		#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(True)
	

	def _setup_modes(self):

		common = CompoundMode(self._mixer,
									self._session_ring)
		main_buttons=CompoundMode(self._mixer.main_buttons_layer, 
									self._transport,
									self._recorder,
									self._recorder.main_layer, 
									self._device,)
		shifted_main_buttons=CompoundMode(self._mixer.solo_buttons_layer, 
									self._recorder, 
									self._recorder.shift_layer,
									self._session.scene_launch_layer,
									self._device,)
		main_faders=CompoundMode(self._mixer.main_faders_layer, 
									self._mixer.master_fader_layer)
		main_dials=CompoundMode(self._view_control,
									self._view_control.main_layer,
									self._device_navigator,
									self._device_navigator.select_dial_layer,
									self.encoder_navigation_on)
		shifted_dials=CompoundMode(self._session_navigation,
									self._session_navigation.nav_dial_layer,
									self._device_navigator,
									self._device_navigator.select_dial_layer,
									self.encoder_navigation_on)

		self._modalt_mode = ModesComponent(name = 'ModAltMode')
		self._modalt_mode.add_mode('disabled', None)
		self._modalt_mode.add_mode('enabled', [tuple([self._enable_mod_alt, self._disable_mod_alt])], behaviour = CancellableBehaviourWithRelease(), cycle_mode_button_color = 'Mod.AltOn')
		self._modalt_mode.selected_mode = 'disabled'
		self._modalt_mode.set_enabled(False)
		self._modalt_mode.layer = Layer(priority = 4, enabled_button = self._encoder_button[1])

		self._modswitcher = ModesComponent(name = 'ModSwitcher')
		self._modswitcher.add_mode('mod', [self.modhandler, self._modalt_mode, main_faders, self._mixer.main_knobs_layer, self._device, main_dials, DelayMode(self.modhandler.update, delay = .5, parent_task_group = self._task_group)])
		self._modswitcher.add_mode('instrument', [self._instrument.shift_button_layer, main_buttons, main_faders, self._mixer.main_knobs_layer, self._device, self._device.main_layer, self._device_navigator, self._device_navigator.main_layer, self._device_navigator.select_dial_layer]) #self._instrument.shift_button_layer, self._optional_translations])
		self._modswitcher.selected_mode = 'instrument'
		self._modswitcher.set_enabled(False)

		self._instrument._main_modes = ModesComponent(name = 'InstrumentModes')
		self._instrument._main_modes.add_mode('disabled', [main_buttons, 
																					main_dials, 
																					self._device.main_layer, 
																					self._session, 
																					self._session, 
																					self._session.clip_launch_layer])
		self._instrument._main_modes.add_mode('drumpad', [self._instrument._drumpad.sequencer_layer, 
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_split', [self._instrument._drumpad.split_layer,
																					self._instrument._selected_session,
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer', [self._instrument._drumpad.sequencer_layer, 
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_shifted', [self._instrument._drumpad.sequencer_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_split_shifted', [self._instrument._drumpad.split_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer_shifted', [self._instrument._drumpad.sequencer_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad', [self._instrument._keypad.sequencer_layer, 
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_split', [self._instrument._keypad.split_layer,
																					self._instrument._selected_session,
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer', [self._instrument._keypad.sequencer_layer, 
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_shifted', [self._instrument._keypad.sequencer_shift_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_split_shifted', [self._instrument._keypad.split_layer, 
																					self._instrument.keypad_shift_layer,
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer_shifted', [self._instrument._keypad.sequencer_shift_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_session', [self._instrument._drumpad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_split_session', [self._instrument._drumpad.split_session_layer,
																					self._instrument._selected_session,
																					main_buttons,
																					self._device.main_layer,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer_session', [self._instrument._drumpad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session,  
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_shifted_session', [self._instrument._drumpad.sequencer_session_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_split_shifted_session', [self._instrument._drumpad.split_session_layer,
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer_shifted_session', [self._instrument._drumpad.sequencer_session_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_session', [self._instrument._keypad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session, 
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_split_session', [self._instrument._keypad.split_session_layer,
																					self._instrument._selected_session,
																					main_buttons,
																					self._device.main_layer,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer_session', [self._instrument._keypad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session, 
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_shifted_session', [self._instrument._keypad.sequencer_session_shift_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_split_shifted_session', [self._instrument._keypad.split_session_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer_shifted_session', [self._instrument._keypad.sequencer_session_shift_layer,
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])

		self._instrument._main_modes.add_mode('audioloop', [self._instrument.audioloop_layer, 
																					main_buttons,
																					self._device.main_layer,
																					main_dials,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1)])
		self._instrument._main_modes.add_mode('audioloop_shifted', [self._instrument.audioloop_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		#self._instrument._main_modes.add_mode('audioloop_shifted_session', [self._instrument.audioloop_layer, self._session, shifted_main_buttons, main_dials, shifted_dials])
		self._instrument.register_component(self._instrument._main_modes)
		self._instrument._main_modes.selected_mode = 'disabled'
		self._instrument.set_enabled(True)

		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('disabled', [self._background])
		self._main_modes.add_mode('MixMode', [common, 
													self._instrument, 
													self._instrument.shift_button_layer,
													self._mixer,
													main_faders, 
													self._mixer.main_knobs_layer,
													self._device,
													self._device.main_layer,
													self._device_navigator,
													self._device_navigator.main_layer,
													self._device_navigator.select_dial_layer])
		self._main_modes.add_mode('ModSwitcher', [common,
													main_faders, 
													main_dials, 
													self._mixer.main_knobs_layer,
													self._view_control,
													self._view_control.main_layer,
													self._device_navigator,
													self._device_navigator.select_dial_layer, 
													self.encoder_navigation_on, 
													self._modswitcher, 
													DelayMode(self._update_modswitcher, delay = .1)], 
													behaviour = ColoredCancellableBehaviourWithRelease(color = 'ModeButtons.ModSwitcher', off_color = 'ModeButtons.ModSwitcherDisabled'))
		self._main_modes.add_mode('Translations', [common, 
													main_faders, 
													main_dials,
													self._mixer.main_knobs_layer, 
													self._translations, 
													DelayMode(self._translations.selector_layer, delay = .1)], 
													behaviour = DefaultedBehaviour(default_mode = 'MixMode', color = 'ModeButtons.Translations', off_color = 'ModeButtons.TranslationsDisabled'))
		self._main_modes.add_mode('DeviceSelector', [common,
													self._device_selector,
													DelayMode(self._device_selector.select_layer, delay = .1),
													DelayMode(self.modhandler.lock_layer, delay = .1),
													DelayMode(self._device_selector.assign_layer, delay = .5), 
													main_buttons,
													main_dials, 
													main_faders, 
													self._mixer.main_knobs_layer, 
													self._device.main_layer,
													self._device_navigator,
													self._device_navigator.main_layer,
													self._device_navigator.select_dial_layer], 
													behaviour = ColoredCancellableBehaviourWithRelease(color = 'ModeButtons.DeviceSelector', off_color = 'ModeButtons.DeviceSelectorDisabled'))
		self._main_modes.layer = Layer(priority = 4, ModSwitcher_button = self._encoder_button[2], DeviceSelector_button = self._encoder_button[0], Translations_button = self._encoder_button[3]) #, 
		self._main_modes.selected_mode = 'disabled'
		self._main_modes.set_enabled(True)

		self._test.subject = self._instrument._main_modes
	

	def _setup_modes(self):
		pass
	

	def _setup_m4l_interface(self):
		self._m4l_interface = M4LInterfaceComponent(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')
	

	def _get_num_tracks(self):
		return self.num_tracks
	



#	a
Example #17
0
class Cntrlr(LividControlSurface):
	__module__ = __name__
	__doc__ = " Monomodular controller script for Livid CNTRLR "


	_sysex_id = 8
	_model_name = 'Cntrlr'
	_host_name = 'Cntrlr'
	monomodular = None

	device_provider_class = ModDeviceProvider

	def __init__(self, *a, **k):
		super(Cntrlr, self).__init__(*a, **k)
		self._skin = Skin(CntrlrColors)
		self._device_selection_follows_track_selection = FOLLOW
		with self.component_guard():
			self._setup_controls()
			self._define_sysex()
			self._setup_background()
			#self._setup_autoarm()
			self._setup_viewcontrol()
			self._setup_session_control()
			self._setup_mixer_control()
			self._setup_transport_control()
			#self._setup_device_control()
			#self._setup_device_selector()
			#self._setup_session_recording_component()
			#self._setup_modes()
			self._setup_m4l_interface()
	

	def _initialize_script(self):
		super(Cntrlr, self)._initialize_script()
		self._connected = True
		#self._main_modes.selected_mode = 'MixMode'

		self._session_ring._update_highlight()
		self._session_ring.track_offset = 0
		if liveobj_valid(self.song.visible_tracks[0]):
			self.song.view.selected_track = self.song.visible_tracks[0]
	

	def _setup_controls(self):
		is_momentary = True
		optimized = True
		resource = PrioritizedResource
		self._fader = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_FADERS[index], name = 'Fader_' + str(index), num = index, script = self,  optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(8)]
		self._dial_left = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_KNOBS_LEFT[index], name = 'Dial_Left_' + str(index), num = CNTRLR_KNOBS_LEFT[index], script = self, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)]
		self._dial_right = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_KNOBS_RIGHT[index], name = 'Dial_Right_' + str(index), num = CNTRLR_KNOBS_RIGHT[index], script = self, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)]
		self._encoder = [CodecEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_DIALS[index], name = 'Encoder_' + str(index), num = CNTRLR_DIALS[index], script = self, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)] 
		self._encoder_button = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CNTRLR_DIAL_BUTTONS[index], name = 'Encoder_Button_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)]	
		self._grid = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CNTRLR_GRID[index], name = 'Grid_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(16)]
		self._button = [MonoButtonElement(is_momentary = is_momentary,msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CNTRLR_BUTTONS[index], name = 'Button_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) 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 _setup_background(self):
		self._background = BackgroundComponent(name = 'Background')
		self._background.layer = Layer(priority = 3, matrix = self._matrix.submatrix[:,:], faders = self._fader_matrix.submatrix[:,:], left_knobs = self._knob_left_matrix.submatrix[:,:], right_knobs = self._knob_right_matrix.submatrix[:,:], dials = self._dial_matrix, dial_buttons = self._dial_button_matrix.submatrix[:,:], keys = self._key_matrix.submatrix[:,:])
		self._background.set_enabled(True)
	

	def _define_sysex(self):
		#self.encoder_navigation_on = SendLividSysexMode(livid_settings = self._livid_settings, call = 'set_encoder_encosion_mode', message = [13, 0, 0, 0]) 
		pass
	

	def _setup_transport_control(self):
		self._transport = CntrlrTransportComponent(name = 'Transport') 
		self._transport._play_toggle.view_transform = lambda value: 'Transport.PlayOn' if value else 'Transport.PlayOff'
		self._transport._record_toggle.view_transform = lambda value: 'Transport.RecordOn' if value else 'Transport.RecordOff'
		self._transport._nudge_up_toggle.view_transform = lambda value: 'Transport.NudgeOn' if value else 'Transport.NudgeOff'
		self._transport._nudge_down_toggle.view_transform = lambda value: 'Transport.NudgeOn' if value else 'Transport.NudgeOff'
		self._transport._loop_toggle.view_transform = lambda value: 'Transport.LoopOn' if value else 'Transport.LoopOff'
		self._transport.layer = Layer(priority = 4,
									play_button = self._button[28],
									stop_button = self._button[29],
									record_button = self._button[30],
									tap_tempo_button = self._button[31],
									nudge_up_button = self._button[3],
									nudge_down_button = self._button[19],
									loop_button = self._button[23])
		self._transport.set_enabled(True)
	

	def _setup_autoarm(self):
		self._auto_arm = CntrlrAutoArmComponent(name='Auto_Arm')
		#self._auto_arm._update_notification = lambda a: None
		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 = FixedLengthSessionRecordingComponent(clip_creator = self._clip_creator, view_controller = ViewControlComponent(), name = 'SessionRecorder') # is_enabled = False)
		self._recorder.main_layer = AddLayerMode(self._recorder, Layer(priority = 4, record_button = self._button[29]))
		#self._recorder.shift_layer = AddLayerMode(self._recorder, Layer(priority = 4, automation_button = self._button[29]))
		self._recorder.set_enabled(False)
	

	def _setup_session_control(self):
		self._session_ring = SessionRingComponent(num_tracks = 4, num_scenes = 4)
		self._session_ring.set_enabled(True)

		self._session_navigation = SessionNavigationComponent(name = 'SessionNavigation', session_ring = self._session_ring)

		self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_up_button.disabled_color = 'Session.PageNavigationButtonOff'
		self._session_navigation._vertical_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_down_button.disabled_color = 'Session.PageNavigationButtonOff'
		self._session_navigation._horizontal_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_up_button.disabled_color = 'Session.PageNavigationButtonOff'
		self._session_navigation._horizontal_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_down_button.disabled_color = 'Session.PageNavigationButtonOff'

		self._session_navigation.layer = Layer(priority = 4,
									down_button = self._button[14],
									up_button = self._button[15],
									left_button = self._button[12],
									right_button = self._button[13])
		self._session_navigation.set_enabled(True)

		self._session = SessionComponent(session_ring = self._session_ring, auto_name = True)
		hasattr(self._session, '_enable_skinning') and self._session._enable_skinning()
		self._session.layer = Layer(priority = 4,
									clip_launch_buttons = self._matrix.submatrix[:,:])
		self._session.set_enabled(True)
	

	def _setup_mixer_control(self):
		self._mixer_session_ring = SessionRingComponent(num_tracks = 4, num_scenes = 4)
		self._mixer = MonoMixerComponent(name = 'Mixer', tracks_provider = self._mixer_session_ring, track_assigner = simple_track_assigner, invert_mute_feedback = True, auto_name = True, enable_skinning = True)

		self._mixer.layer = Layer(priority = 4, 
											solo_buttons = self._key_matrix.submatrix[8:11, 0],
											stop_clip_buttons = self._key_matrix.submatrix[:3, 0],
											track_select_buttons = self._key_matrix.submatrix[4:8, 0],)
		for strip in self._mixer._channel_strips:
			strip._on_select_button_double_clicked = self._toggle_view
		self._mixer.set_enabled(True)
	

	def _toggle_view(self, *a):
		debug('toggle_view')
		debug('Clip is visible:', self.application.view.is_view_visible('Detail/Clip'))
		debug('Device is visible:', self.application.view.is_view_visible('Detail/DeviceChain'))
		if self.application.view.is_view_visible('Detail/Clip'):
			self._view_control.show_view('Detail/DeviceChain')
		else:
			self._view_control.show_view('Detail/Clip')

	def _setup_device_control(self):
		self._device_selection_follows_track_selection = FOLLOW
		self._device = DeviceComponent(name = 'Device_Component', device_provider = self._device_provider, device_bank_registry = DeviceBankRegistry())
		self._device.layer = Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:, 1:3],)
		#self._device.mod_layer = AddLayerMode(self._device, Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:, 1:3],))
		self._device.main_layer = AddLayerMode(self._device, Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:, 1:3], 
												on_off_button = self._encoder_button[4],
												bank_prev_button = self._encoder_button[6],
												bank_next_button = self._encoder_button[7],))
												#lock_button = self._encoder_button[5],
		self._device.set_enabled(False)

		self._device_navigator = DeviceNavigator(self._device_provider, self._mixer, self)
		self._device_navigator.name = 'Device_Navigator'
		self._device_navigator.select_dial_layer = AddLayerMode(self._device_navigator, Layer(priority = 6, device_select_dial = self._encoder[0],))
		self._device_navigator.main_layer = AddLayerMode(self._device_navigator, Layer(priority = 4, 
											prev_chain_button = self._encoder_button[8], 
											next_chain_button = self._encoder_button[9], 
											exit_button = self._encoder_button[10], 
											enter_button = self._encoder_button[11],))
		self._device_navigator.set_enabled(False)
	

	def _setup_device_selector(self):
		self._device_selector = DeviceSelectorComponent(self)
		self._device_selector.name = 'Device_Selector'
		#self._device_selector.select_layer = AddLayerMode(self._device_selector, Layer(priority = 6 , matrix = self._matrix.submatrix[:, :]))
		self._device_selector.select_layer = AddLayerMode(self._device_selector, Layer(priority = 6, matrix = ButtonMatrixElement(rows = [self._grid[:4],self._grid[4:8],self._grid[8:12],self._grid[12:14]])))
		self._device_selector.assign_layer = AddLayerMode(self._device_selector, Layer(priority = 7, assign_button = self._grid[14]))
		self._device_selector.set_enabled(False)
	

	def _setup_viewcontrol(self):
		self._view_control = ViewControlComponent(name='View_Control')
		#self._view_control.main_layer = AddLayerMode(self._view_control, Layer(priority = 5, 
		#																		scene_select_dial = self._encoder[2],
		#																		track_select_dial = self._encoder[3],))
		#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(True)
	

	def _setup_modes(self):

		common = CompoundMode(self._mixer,
									self._session_ring)
		main_buttons=CompoundMode(self._mixer.main_buttons_layer, 
									self._transport,
									self._recorder,
									self._recorder.main_layer, 
									self._device,)
		shifted_main_buttons=CompoundMode(self._mixer.solo_buttons_layer, 
									self._recorder, 
									self._recorder.shift_layer,
									self._session.scene_launch_layer,
									self._device,)
		main_faders=CompoundMode(self._mixer.main_faders_layer, 
									self._mixer.master_fader_layer)
		main_dials=CompoundMode(self._view_control,
									self._view_control.main_layer,
									self._device_navigator,
									self._device_navigator.select_dial_layer,
									self.encoder_navigation_on)
		shifted_dials=CompoundMode(self._session_navigation,
									self._session_navigation.nav_dial_layer,
									self._device_navigator,
									self._device_navigator.select_dial_layer,
									self.encoder_navigation_on)

		self._modalt_mode = ModesComponent(name = 'ModAltMode')
		self._modalt_mode.add_mode('disabled', None)
		self._modalt_mode.add_mode('enabled', [tuple([self._enable_mod_alt, self._disable_mod_alt])], behaviour = CancellableBehaviourWithRelease(), cycle_mode_button_color = 'Mod.AltOn')
		self._modalt_mode.selected_mode = 'disabled'
		self._modalt_mode.set_enabled(False)
		self._modalt_mode.layer = Layer(priority = 4, enabled_button = self._encoder_button[1])

		self._modswitcher = ModesComponent(name = 'ModSwitcher')
		self._modswitcher.add_mode('mod', [self.modhandler, self._modalt_mode, main_faders, self._mixer.main_knobs_layer, self._device, main_dials, DelayMode(self.modhandler.update, delay = .5, parent_task_group = self._task_group)])
		self._modswitcher.add_mode('instrument', [self._instrument.shift_button_layer, main_buttons, main_faders, self._mixer.main_knobs_layer, self._device, self._device.main_layer, self._device_navigator, self._device_navigator.main_layer, self._device_navigator.select_dial_layer]) #self._instrument.shift_button_layer, self._optional_translations])
		self._modswitcher.selected_mode = 'instrument'
		self._modswitcher.set_enabled(False)

		self._instrument._main_modes = ModesComponent(name = 'InstrumentModes')
		self._instrument._main_modes.add_mode('disabled', [main_buttons, 
																					main_dials, 
																					self._device.main_layer, 
																					self._session, 
																					self._session, 
																					self._session.clip_launch_layer])
		self._instrument._main_modes.add_mode('drumpad', [self._instrument._drumpad.sequencer_layer, 
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_split', [self._instrument._drumpad.split_layer,
																					self._instrument._selected_session,
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer', [self._instrument._drumpad.sequencer_layer, 
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_shifted', [self._instrument._drumpad.sequencer_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_split_shifted', [self._instrument._drumpad.split_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer_shifted', [self._instrument._drumpad.sequencer_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad', [self._instrument._keypad.sequencer_layer, 
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_split', [self._instrument._keypad.split_layer,
																					self._instrument._selected_session,
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer', [self._instrument._keypad.sequencer_layer, 
																					main_buttons,
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_shifted', [self._instrument._keypad.sequencer_shift_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_split_shifted', [self._instrument._keypad.split_layer, 
																					self._instrument.keypad_shift_layer,
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer_shifted', [self._instrument._keypad.sequencer_shift_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_session', [self._instrument._drumpad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_split_session', [self._instrument._drumpad.split_session_layer,
																					self._instrument._selected_session,
																					main_buttons,
																					self._device.main_layer,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer_session', [self._instrument._drumpad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session,  
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_shifted_session', [self._instrument._drumpad.sequencer_session_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_split_shifted_session', [self._instrument._drumpad.split_session_layer,
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer_shifted_session', [self._instrument._drumpad.sequencer_session_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_session', [self._instrument._keypad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session, 
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_split_session', [self._instrument._keypad.split_session_layer,
																					self._instrument._selected_session,
																					main_buttons,
																					self._device.main_layer,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer_session', [self._instrument._keypad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session, 
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_shifted_session', [self._instrument._keypad.sequencer_session_shift_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_split_shifted_session', [self._instrument._keypad.split_session_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer_shifted_session', [self._instrument._keypad.sequencer_session_shift_layer,
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])

		self._instrument._main_modes.add_mode('audioloop', [self._instrument.audioloop_layer, 
																					main_buttons,
																					self._device.main_layer,
																					main_dials,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1)])
		self._instrument._main_modes.add_mode('audioloop_shifted', [self._instrument.audioloop_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		#self._instrument._main_modes.add_mode('audioloop_shifted_session', [self._instrument.audioloop_layer, self._session, shifted_main_buttons, main_dials, shifted_dials])
		self._instrument.register_component(self._instrument._main_modes)
		self._instrument._main_modes.selected_mode = 'disabled'
		self._instrument.set_enabled(True)

		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('disabled', [self._background])
		self._main_modes.add_mode('MixMode', [common, 
													self._instrument, 
													self._instrument.shift_button_layer,
													self._mixer,
													main_faders, 
													self._mixer.main_knobs_layer,
													self._device,
													self._device.main_layer,
													self._device_navigator,
													self._device_navigator.main_layer,
													self._device_navigator.select_dial_layer])
		self._main_modes.add_mode('ModSwitcher', [common,
													main_faders, 
													main_dials, 
													self._mixer.main_knobs_layer,
													self._view_control,
													self._view_control.main_layer,
													self._device_navigator,
													self._device_navigator.select_dial_layer, 
													self.encoder_navigation_on, 
													self._modswitcher, 
													DelayMode(self._update_modswitcher, delay = .1)], 
													behaviour = ColoredCancellableBehaviourWithRelease(color = 'ModeButtons.ModSwitcher', off_color = 'ModeButtons.ModSwitcherDisabled'))
		self._main_modes.add_mode('Translations', [common, 
													main_faders, 
													main_dials,
													self._mixer.main_knobs_layer, 
													self._translations, 
													DelayMode(self._translations.selector_layer, delay = .1)], 
													behaviour = DefaultedBehaviour(default_mode = 'MixMode', color = 'ModeButtons.Translations', off_color = 'ModeButtons.TranslationsDisabled'))
		self._main_modes.add_mode('DeviceSelector', [common,
													self._device_selector,
													DelayMode(self._device_selector.select_layer, delay = .1),
													DelayMode(self.modhandler.lock_layer, delay = .1),
													DelayMode(self._device_selector.assign_layer, delay = .5), 
													main_buttons,
													main_dials, 
													main_faders, 
													self._mixer.main_knobs_layer, 
													self._device.main_layer,
													self._device_navigator,
													self._device_navigator.main_layer,
													self._device_navigator.select_dial_layer], 
													behaviour = ColoredCancellableBehaviourWithRelease(color = 'ModeButtons.DeviceSelector', off_color = 'ModeButtons.DeviceSelectorDisabled'))
		self._main_modes.layer = Layer(priority = 4, ModSwitcher_button = self._encoder_button[2], DeviceSelector_button = self._encoder_button[0], Translations_button = self._encoder_button[3]) #, 
		self._main_modes.selected_mode = 'disabled'
		self._main_modes.set_enabled(True)

		self._test.subject = self._instrument._main_modes
	

	def _setup_modes(self):
		pass
	

	def _setup_m4l_interface(self):
		self._m4l_interface = M4LInterfaceComponent(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')
	

	def _get_num_tracks(self):
		return self.num_tracks
	



#	a
class PushBase(ControlSurface):
    preferences_key = 'Push'
    session_component_type = SpecialSessionComponent
    drum_group_note_editor_skin = 'NoteEditor'
    note_editor_velocity_range_thresholds = DEFAULT_VELOCITY_RANGE_THRESHOLDS
    device_component_class = None
    bank_definitions = None
    note_editor_class = None

    def __init__(self, *a, **k):
        super(PushBase, self).__init__(*a, **k)
        self.register_slot(self.song.view, self._on_selected_track_changed, 'selected_track')
        self._device_decorator_factory = self._create_device_decorator_factory()
        self.register_disconnectable(self._device_decorator_factory)
        self._double_press_context = DoublePressContext()
        injecting = self._create_injector()
        self._push_injector = injecting.everywhere()
        self._element_injector = inject(element_container=const(None)).everywhere()
        with self.component_guard():
            self._suppress_sysex = False
            self._skin = self._create_skin()
            self._clip_creator = ClipCreator()
            self._note_editor_settings = []
            self._notification = None
            self._user = None
            with inject(skin=const(self._skin)).everywhere():
                self._create_controls()
        self._element_injector = inject(element_container=const(self.elements)).everywhere()

    def initialize(self):
        self._setup_accidental_touch_prevention()
        self._create_components()
        self._init_main_modes()
        self._on_selected_track_changed()
        self.__on_session_record_changed.subject = self.song
        self.__on_session_record_changed()
        self.__on_selected_track_is_frozen_changed.subject = self.song.view
        self.set_feedback_channels(FEEDBACK_CHANNELS)

    def disconnect(self):
        if self._user is not None:
            with self.component_guard():
                self._user.mode = sysex.USER_MODE
        super(PushBase, self).disconnect()

    @contextmanager
    def _component_guard(self):
        with super(PushBase, self)._component_guard():
            with self._push_injector:
                with self._element_injector:
                    song_view = self.song.view
                    old_selected_track = song_view.selected_track
                    yield
                    if song_view.selected_track != old_selected_track:
                        self._track_selection_changed_by_action()

    def _create_device_decorator_factory(self):
        raise NotImplementedError

    def _create_components(self):
        self._init_settings()
        self._init_notification()
        self._init_message_box()
        self._init_background()
        self._init_user()
        self._init_touch_strip_controller()
        self._init_accent()
        self._init_track_frozen()
        self._init_undo_redo_actions()
        self._init_duplicate_actions()
        self._init_delete_actions()
        self._init_quantize_actions()
        self._init_session_ring()
        self._init_fixed_length()
        self._init_transport_and_recording()
        self._init_stop_clips_action()
        self._init_value_components()
        self._init_track_list()
        self._init_mixer()
        self._init_track_mixer()
        self._init_session()
        self._init_grid_resolution()
        self._init_drum_component()
        self._init_slicing_component()
        self._init_automation_component()
        self._init_note_settings_component()
        self._init_note_editor_settings_component()
        self._init_step_sequencer()
        self._init_instrument()
        self._init_scales()
        self._init_note_repeat()
        self._init_matrix_modes()
        self._init_device()
        self._init_m4l_interface()

    def _create_injector(self):
        return inject(double_press_context=const(self._double_press_context), expect_dialog=const(self.expect_dialog), show_notification=const(self.show_notification), selection=lambda : PushSelection(application=self.application(), device_component=self._device_component, navigation_component=self._device_navigation))

    def _create_skin(self):
        return make_default_skin()

    def _needs_to_deactivate_session_recording(self):
        return self._matrix_modes.selected_mode == 'note' and self.song.exclusive_arm

    def _track_selection_changed_by_action(self):
        if self._needs_to_deactivate_session_recording():
            self._session_recording.deactivate_recording()
        if self._auto_arm.needs_restore_auto_arm:
            self._auto_arm.restore_auto_arm()

    def port_settings_changed(self):
        self._switch_to_live_mode()

    def _switch_to_live_mode(self):
        self._user.mode = sysex.LIVE_MODE
        self._user.force_send_mode()

    def _init_settings(self):
        self._settings = self._create_settings()

    def _create_settings(self):
        raise RuntimeError

    def update(self):
        self.__on_session_record_changed()
        self.reset_controlled_track()
        self.set_feedback_channels(FEEDBACK_CHANNELS)
        super(PushBase, self).update()

    def _create_controls(self):
        raise NotImplementedError

    def _with_shift(self, button):
        return ComboElement(button, modifier='shift_button')

    def _with_firmware_version(self, major_version, minor_version, control_element):
        raise NotImplementedError

    def _init_background(self):
        self._background = BackgroundComponent(is_root=True)
        self._background.layer = self._create_background_layer()
        self._matrix_background = BackgroundComponent()
        self._matrix_background.set_enabled(False)
        self._matrix_background.layer = Layer(matrix='matrix')
        self._mod_background = ModifierBackgroundComponent(is_root=True)
        self._mod_background.layer = Layer(shift_button='shift_button', select_button='select_button', delete_button='delete_button', duplicate_button='duplicate_button', quantize_button='quantize_button')

    def _create_background_layer(self):
        return Layer(top_buttons='select_buttons', bottom_buttons='track_state_buttons', scales_button='scale_presets_button', octave_up='octave_up_button', octave_down='octave_down_button', side_buttons='side_buttons', repeat_button='repeat_button', accent_button='accent_button', double_button='double_button', param_controls='global_param_controls', param_touch='global_param_touch_buttons', touch_strip='touch_strip_control', nav_up_button='nav_up_button', nav_down_button='nav_down_button', nav_left_button='nav_left_button', nav_right_button='nav_right_button', aftertouch='aftertouch_control', _notification=self._notification.use_single_line(2), priority=consts.BACKGROUND_PRIORITY)

    def _init_track_list(self):
        pass

    def _can_auto_arm_track(self, track):
        routing = track.current_input_routing
        return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith(self.input_target_name_for_auto_arm)

    def _init_touch_strip_controller(self):
        strip_controller = TouchStripControllerComponent()
        strip_controller.set_enabled(False)
        strip_controller.layer = Layer(touch_strip='touch_strip_control')
        strip_controller.layer.priority = consts.DIALOG_PRIORITY
        self._strip_connection = TouchStripEncoderConnection(strip_controller, self.elements.touch_strip_tap, is_root=True)
        self.elements.tempo_control.set_observer(self._strip_connection)
        self.elements.swing_control.set_observer(self._strip_connection)
        self.elements.master_volume_control.set_observer(self._strip_connection)
        for encoder in self.elements.global_param_controls.nested_control_elements():
            encoder.set_observer(self._strip_connection)

        self._pitch_mod_touch_strip = TouchStripPitchModComponent()
        self._pitch_mod_touch_strip_layer = Layer(touch_strip='touch_strip_control', touch_strip_indication=self._with_firmware_version(1, 16, ComboElement('touch_strip_control', modifier='select_button')), touch_strip_toggle=self._with_firmware_version(1, 16, ComboElement('touch_strip_tap', modifier='select_button')))

    def _create_session_mode(self):
        raise NotImplementedError

    def _create_slicing_modes(self):
        slicing_modes = ModesComponent(name='Slicing_Modes', is_enabled=False)
        slicing_modes.add_mode('64pads', [AddLayerMode(self._slicing_component, Layer(matrix='matrix')), LayerMode(self._pitch_mod_touch_strip, self._pitch_mod_touch_strip_layer)])
        slicing_modes.add_mode('sequencer', [self._slice_step_sequencer, self._note_editor_settings_component, AddLayerMode(self._slicing_component, Layer(matrix=self.elements.matrix.submatrix[:4, 4:8], page_strip='touch_strip_control', scroll_strip=self._with_shift('touch_strip_control')))])
        slicing_modes.selected_mode = '64pads'
        return slicing_modes

    def _init_matrix_modes(self):
        self._auto_arm = AutoArmComponent(name='Auto_Arm')
        self._auto_arm.can_auto_arm_track = self._can_auto_arm_track
        self._auto_arm.layer = Layer(_notification=self._notification.use_single_line(2))
        self._select_playing_clip = SelectPlayingClipComponent(name='Select_Playing_Clip', playing_clip_above_layer=Layer(action_button='nav_up_button'), playing_clip_below_layer=Layer(action_button='nav_down_button'))
        self._select_playing_clip.layer = Layer(_notification=self._notification.use_single_line(2))
        self._percussion_instrument_finder = PercussionInstrumentFinderComponent(device_parent=self.song.view.selected_track)
        self.__on_percussion_instrument_changed.subject = self._percussion_instrument_finder
        self._drum_modes = ModesComponent(name='Drum_Modes', is_enabled=False)
        self._drum_modes.add_mode('sequencer', [self._drum_step_sequencer, self._note_editor_settings_component, AddLayerMode(self._drum_component, Layer(matrix=self.elements.matrix.submatrix[:4, 4:8]))])
        self._drum_modes.add_mode('64pads', [AddLayerMode(self._drum_component, Layer(matrix='matrix'))])
        self._drum_modes.selected_mode = 'sequencer'
        self._slicing_modes = self._create_slicing_modes()
        self._note_modes = ModesComponent(name='Note_Modes')
        self._note_modes.add_mode('drums', [self._drum_component,
         self._note_repeat_enabler,
         self._accent_component,
         self._drum_modes])
        self._note_modes.add_mode('slicing', [self._slicing_component,
         self._note_repeat_enabler,
         self._accent_component,
         self._slicing_modes])
        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._accent_component,
         self._instrument,
         self._scales_enabler])
        self._note_modes.add_mode('disabled', self._matrix_background)
        self._note_modes.selected_mode = 'disabled'
        self._note_modes.set_enabled(False)
        self._matrix_modes = ModesComponent(name='Matrix_Modes', is_root=True)
        self._matrix_modes.add_mode('session', self._create_session_mode())
        self._matrix_modes.add_mode('note', self._create_note_mode(), behaviour=self._create_note_mode_behaviour())
        self._matrix_modes.selected_mode = 'note'
        self._matrix_modes.layer = Layer(session_button='session_mode_button', note_button='note_mode_button')
        self.__on_matrix_mode_changed.subject = self._matrix_modes
        self._matrix_modes.selected_mode = 'note'

    def _switch_note_mode_layout(self):
        cyclable_mode = {'instrument': self._instrument,
         'drums': self._drum_modes,
         'slicing': self._slicing_modes}.get(self._note_modes.selected_mode, None)
        getattr(cyclable_mode, 'cycle_mode', nop)()

    def _create_note_mode(self):
        return [self._percussion_instrument_finder,
         self._view_control,
         self._note_modes,
         self._delete_clip,
         self._select_playing_clip]

    def _create_note_mode_behaviour(self):
        raise NotImplementedError

    def _init_accent(self):
        self._accent_component = AccentComponent()
        self._accent_component.set_full_velocity(self._c_instance.full_velocity)
        self._accent_component.set_enabled(False)
        self._accent_component.layer = Layer(cycle_mode_button='accent_button')
        self.__on_accent_mode_changed.subject = self._accent_component

    def _create_user_component(self):
        raise NotImplementedError

    def _init_user(self):
        self._user = self._create_user_component()
        self.__on_hardware_mode_changed.subject = self._user
        self.__on_before_hardware_mode_sent.subject = self._user
        self.__on_after_hardware_mode_sent.subject = self._user

    def _create_session_layer(self):
        return Layer(clip_launch_buttons='matrix', scene_launch_buttons='side_buttons', duplicate_button='duplicate_button', touch_strip='touch_strip_control')

    def _set_session_skin(self, session):
        pass

    def _create_session(self):
        session = self.session_component_type(session_ring=self._session_ring, enable_skinning=True, is_enabled=False, auto_name=True, layer=self._create_session_layer())
        self._set_session_skin(session)
        for scene_index in xrange(8):
            scene = session.scene(scene_index)
            scene.layer = Layer(select_button='select_button', delete_button='delete_button')
            scene._do_select_scene = self.on_select_scene
            for track_index in xrange(8):
                clip_slot = scene.clip_slot(track_index)
                clip_slot._do_select_clip = self.on_select_clip_slot
                clip_slot.layer = Layer(delete_button='delete_button', select_button='select_button', duplicate_button='duplicate_button')

        session.duplicate_layer = Layer(scene_buttons='side_buttons')
        return session

    def on_select_clip_slot(self, clip_slot):
        """
        Called when a clip slot is selected from Push. Override to create specific
        behaviour.
        """
        pass

    def on_select_scene(self, scene):
        """
        Called when a scene is selected from Push. Override to create specific behaviour.
        """
        pass

    def on_select_track(self, track):
        """
        Called when a track is selected from Push's channel strip components. Override
        to create specific behaviour.
        """
        pass

    def _create_session_overview(self):
        return SessionOverviewComponent(session_ring=self._session_ring, name='Session_Overview', enable_skinning=True, is_enabled=False, layer=self._create_session_overview_layer())

    def _create_session_overview_layer(self):
        raise NotImplementedError

    def _init_session_ring(self):
        self._session_ring = SessionRingComponent(num_tracks=NUM_TRACKS, num_scenes=NUM_SCENES, tracks_to_use=partial(tracks_to_use_from_song, self.song), is_enabled=True, is_root=True)

    def _init_session(self):
        self._session_mode = LazyComponentMode(self._create_session)
        self._session_overview_mode = LazyComponentMode(self._create_session_overview)
        self._session_navigation = SessionNavigationComponent(session_ring=self._session_ring, is_enabled=False, layer=self._create_session_navigation_layer())

    def _create_session_navigation_layer(self):
        return Layer(left_button='nav_left_button', right_button='nav_right_button', up_button='nav_up_button', down_button='nav_down_button', page_left_button=self._with_shift('nav_left_button'), page_right_button=self._with_shift('nav_right_button'), page_up_button=MultiElement('octave_up_button', self._with_shift('nav_up_button')), page_down_button=MultiElement('octave_down_button', self._with_shift('nav_down_button')))

    def _create_track_modes_layer(self):
        return Layer(stop_button='global_track_stop_button', mute_button='global_mute_button', solo_button='global_solo_button')

    def _when_track_is_not_frozen(self, *modes):
        return TrackFrozenModesComponent(default_mode=[modes], frozen_mode=self._track_frozen_info, is_enabled=False)

    def _create_device_mode(self):
        raise NotImplementedError

    def _create_main_mixer_modes(self):
        self._main_modes.add_mode('volumes', [self._track_modes, (self._mixer, self._mixer_volume_layer), self._track_note_editor_mode])
        self._main_modes.add_mode('pan_sends', [self._track_modes, (self._mixer, self._mixer_pan_send_layer), self._track_note_editor_mode])
        self._main_modes.add_mode('track', [self._track_modes,
         self._track_mixer,
         (self._mixer, self._mixer_track_layer),
         self._track_note_editor_mode])

    def _create_clip_mode(self):
        return [self._when_track_is_not_frozen(partial(self._view_control.show_view, 'Detail/Clip'), LazyComponentMode(self._create_clip_control))]

    def _init_main_modes(self):

        def configure_note_editor_settings(parameter_provider, mode):
            for note_editor_setting in self._note_editor_settings:
                note_editor_setting.component.parameter_provider = parameter_provider
                note_editor_setting.component.automation_layer = getattr(note_editor_setting, mode + '_automation_layer')

        self._track_note_editor_mode = partial(configure_note_editor_settings, self._track_parameter_provider, 'track')
        self._device_note_editor_mode = partial(configure_note_editor_settings, self._device_component, 'device')
        self._enable_stop_mute_solo_as_modifiers = AddLayerMode(self._mod_background, Layer(stop='global_track_stop_button', mute='global_mute_button', solo='global_solo_button'))
        self._main_modes = ModesComponent(is_root=True)
        self._create_main_mixer_modes()
        self._main_modes.add_mode('clip', self._create_clip_mode())
        self._main_modes.add_mode('device', self._create_device_mode(), behaviour=ReenterBehaviour(self._device_navigation.back_to_top))
        self._init_browse_mode()
        self._main_modes.selected_mode = 'device'
        self._main_modes.layer = self._create_main_modes_layer()

    def _init_browse_mode(self):
        raise NotImplementedError

    def _create_main_modes_layer(self):
        return Layer(volumes_button='vol_mix_mode_button', pan_sends_button='pan_send_mix_mode_button', track_button='single_track_mix_mode_button', clip_button='clip_mode_button', device_button='device_mode_button', browse_button='browse_mode_button', add_effect_right_button='create_device_button', add_effect_left_button=self._with_shift('create_device_button'), add_instrument_track_button='create_track_button')

    def _init_track_frozen(self):
        self._track_frozen_info = InfoComponent(info_text=consts.MessageBoxText.TRACK_FROZEN_INFO, is_enabled=False, layer=self._create_track_frozen_layer())

    def _create_track_frozen_layer(self):
        return Layer()

    def _init_mixer(self):
        pass

    def _init_track_mixer(self):
        self._track_parameter_provider = self.register_disconnectable(SelectedTrackParameterProvider())
        self._track_mixer = DeviceParameterComponent(parameter_provider=self._track_parameter_provider, is_enabled=False, layer=self._create_track_mixer_layer())

    def _create_track_mixer_layer(self):
        return Layer(parameter_controls='fine_grain_param_controls')

    def _create_device_component(self):
        return self.device_component_class(device_decorator_factory=self._device_decorator_factory, device_bank_registry=self._device_bank_registry, banking_info=self._banking_info, name='DeviceComponent', is_enabled=True, is_root=True)

    def _create_device_parameter_component(self):
        return DeviceParameterComponent(parameter_provider=self._device_component, is_enabled=False, layer=self._create_device_parameter_layer())

    def _create_device_parameter_layer(self):
        return Layer(parameter_controls='fine_grain_param_controls')

    def _create_device_navigation(self):
        raise NotImplementedError

    def _init_device(self):
        self._device_bank_registry = DeviceBankRegistry()
        self._banking_info = BankingInfo(self.bank_definitions)
        self._device_component = self._create_device_component()
        self._device_parameter_component = self._create_device_parameter_component()
        self._device_navigation = self._create_device_navigation()

    def _create_view_control_component(self):
        return ViewControlComponent(name='View_Control')

    def _init_fixed_length(self):
        self._fixed_length_setting = FixedLengthSetting()
        self._fixed_length_setting.enabled = self.preferences.setdefault('fixed_length_enabled', False)
        self._fixed_length_setting.selected_index = self.preferences.setdefault('fixed_length_option', DEFAULT_LENGTH_OPTION_INDEX)
        self.__on_fixed_length_enabled_changed.subject = self._fixed_length_setting
        self.__on_fixed_length_selected_index_changed.subject = self._fixed_length_setting
        self._fixed_length_settings_component = FixedLengthSettingComponent(fixed_length_setting=self._fixed_length_setting, is_enabled=False)
        self._fixed_length = FixedLengthComponent(settings_component=self._fixed_length_settings_component, fixed_length_setting=self._fixed_length_setting)
        self._fixed_length.layer = Layer(fixed_length_toggle_button='fixed_length_button')

    def _create_session_recording(self):
        raise NotImplementedError

    def _init_transport_and_recording(self):
        self._view_control = self._create_view_control_component()
        self._view_control.set_enabled(False)
        self._view_control.layer = Layer(prev_track_button='nav_left_button', next_track_button='nav_right_button', prev_scene_button=OptionalElement('nav_up_button', self._settings['workflow'], False), next_scene_button=OptionalElement('nav_down_button', self._settings['workflow'], False), prev_scene_list_button=OptionalElement('nav_up_button', self._settings['workflow'], True), next_scene_list_button=OptionalElement('nav_down_button', self._settings['workflow'], True))
        self._session_recording = self._create_session_recording()
        new_button = MultiElement(self.elements.new_button, self.elements.foot_pedal_button.double_press)
        self._session_recording.layer = Layer(new_button=OptionalElement(new_button, self._settings['workflow'], False), scene_list_new_button=OptionalElement(new_button, self._settings['workflow'], True), record_button='record_button', arrangement_record_button=self._with_shift('record_button'), automation_button='automation_button', new_scene_button=self._with_shift('new_button'), re_enable_automation_button=self._with_shift('automation_button'), delete_automation_button=ComboElement('automation_button', 'delete_button'), foot_switch_button=self.elements.foot_pedal_button.single_press, _uses_foot_pedal='foot_pedal_button')
        self._transport = TransportComponent(name='Transport', is_root=True)
        self._transport.layer = Layer(play_button='play_button', stop_button=self._with_shift('play_button'), tap_tempo_button='tap_tempo_button', metronome_button='metronome_button')

    def _create_clip_control(self):
        return ClipControlComponent(loop_layer=self._create_clip_loop_layer(), audio_layer=self._create_clip_audio_layer(), clip_name_layer=self._create_clip_name_layer(), name='Clip_Control', is_enabled=False)

    def _create_clip_loop_layer(self):
        return Layer(encoders=self.elements.global_param_controls.submatrix[:4, :], shift_button='shift_button')

    def _create_clip_audio_layer(self):
        return Layer(warp_mode_encoder='parameter_controls_raw[4]', transpose_encoder='parameter_controls_raw[5]', detune_encoder='parameter_controls_raw[6]', gain_encoder='parameter_controls_raw[7]', shift_button='shift_button')

    def _create_clip_name_layer(self):
        return Layer()

    def _init_grid_resolution(self):
        self._grid_resolution = self.register_disconnectable(GridResolution())

    def _init_note_settings_component(self):
        raise NotImplementedError

    def _init_automation_component(self):
        self._automation_component = AutomationComponent()

    def _init_note_editor_settings_component(self):
        self._note_editor_settings_component = NoteEditorSettingsComponent(note_settings_component=self._note_settings_component, automation_component=self._automation_component, initial_encoder_layer=Layer(initial_encoders='global_param_controls', priority=consts.MOMENTARY_DIALOG_PRIORITY), encoder_layer=Layer(encoders='global_param_controls', priority=consts.MOMENTARY_DIALOG_PRIORITY))
        self._note_editor_settings_component.mode_selector_layer = self._create_note_editor_mode_selector_layer()
        self._note_editor_settings.append(NamedTuple(component=self._note_editor_settings_component, track_automation_layer=self._create_note_editor_track_automation_layer(), device_automation_layer=self._create_note_editor_track_automation_layer()))

    def _create_note_editor_mode_selector_layer(self):
        return Layer(select_buttons='select_buttons', state_buttons='track_state_buttons', priority=consts.MOMENTARY_DIALOG_PRIORITY)

    def _create_note_editor_track_automation_layer(self):
        return Layer(priority=consts.MOMENTARY_DIALOG_PRIORITY)

    def _create_note_editor_device_automation_layer(self):
        return Layer(priority=consts.MOMENTARY_DIALOG_PRIORITY)

    def _create_instrument_layer(self):
        return Layer(playhead='playhead_element', mute_button='global_mute_button', quantization_buttons='side_buttons', loop_selector_matrix=self.elements.double_press_matrix.submatrix[:, 0], short_loop_selector_matrix=self.elements.double_press_event_matrix.submatrix[:, 0], note_editor_matrices=ButtonMatrixElement([[ self.elements.matrix.submatrix[:, 7 - row] for row in xrange(7) ]]))

    def _init_instrument(self):
        self._note_layout = NoteLayout(song=self.song, preferences=self.preferences)
        instrument_basic_layer = Layer(octave_strip=self._with_shift('touch_strip_control'), octave_up_button='octave_up_button', octave_down_button='octave_down_button', scale_up_button=self._with_shift('octave_up_button'), scale_down_button=self._with_shift('octave_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_layout=self._note_layout, note_editor_settings=self._note_editor_settings_component, note_editor_class=self.note_editor_class, velocity_range_thresholds=self.note_editor_velocity_range_thresholds, layer=self._create_instrument_layer(), instrument_play_layer=instrument_basic_layer + Layer(matrix='matrix', aftertouch_control='aftertouch_control', delete_button='delete_button'), instrument_sequence_layer=instrument_basic_layer + Layer(note_strip='touch_strip_control'), pitch_mod_touch_strip_mode=LayerMode(self._pitch_mod_touch_strip, self._pitch_mod_touch_strip_layer))
        self.__on_note_editor_layout_changed.subject = self._instrument

    def _create_scales_enabler(self):
        raise NotImplementedError

    def _init_scales(self):
        self._scales_enabler = self._create_scales_enabler()

    def _create_step_sequencer_layer(self):
        return Layer(playhead='playhead_element', button_matrix=self.elements.matrix.submatrix[:8, :4], loop_selector_matrix=self.elements.double_press_matrix.submatrix[4:8, 4:8], short_loop_selector_matrix=self.elements.double_press_event_matrix.submatrix[4:8, 4:8], quantization_buttons='side_buttons', solo_button='global_solo_button', select_button='select_button', delete_button='delete_button', shift_button='shift_button', mute_button='global_mute_button')

    def _init_step_sequencer(self):
        drum_note_editor = self.note_editor_class(clip_creator=self._clip_creator, grid_resolution=self._grid_resolution, skin_base_key=self.drum_group_note_editor_skin, velocity_range_thresholds=self.note_editor_velocity_range_thresholds)
        self._note_editor_settings_component.add_editor(drum_note_editor)
        self._drum_step_sequencer = StepSeqComponent(self._clip_creator, self._skin, name='Drum_Step_Sequencer', grid_resolution=self._grid_resolution, note_editor_component=drum_note_editor, instrument_component=self._drum_component)
        self._drum_step_sequencer.set_enabled(False)
        self._drum_step_sequencer.layer = self._create_step_sequencer_layer()
        self._audio_loop = LoopSelectorComponent(follow_detail_clip=True, measure_length=1.0, name='Loop_Selector')
        self._audio_loop.set_enabled(False)
        self._audio_loop.layer = Layer(loop_selector_matrix='matrix')
        slice_note_editor = self.note_editor_class(clip_creator=self._clip_creator, grid_resolution=self._grid_resolution, skin_base_key=self.drum_group_note_editor_skin, velocity_range_thresholds=self.note_editor_velocity_range_thresholds)
        self._note_editor_settings_component.add_editor(slice_note_editor)
        self._slice_step_sequencer = StepSeqComponent(self._clip_creator, self._skin, name='Slice_Step_Sequencer', grid_resolution=self._grid_resolution, note_editor_component=slice_note_editor, instrument_component=self._slicing_component, is_enabled=False)
        self._slice_step_sequencer.layer = Layer(playhead='playhead_element', button_matrix=self.elements.matrix.submatrix[:8, :4], loop_selector_matrix=self.elements.double_press_matrix.submatrix[4:8, 4:8], short_loop_selector_matrix=self.elements.double_press_event_matrix.submatrix[4:8, 4:8], quantization_buttons='side_buttons', select_button='select_button')

    def _drum_pad_notification_formatter(self):
        return lambda x: adjust_string(x, 8)

    def _create_drum_component(self):
        raise NotImplementedError

    def _init_drum_component(self):
        self._drum_component = self._create_drum_component()
        self._drum_component.layer = Layer(page_strip='touch_strip_control', scroll_strip=self._with_shift('touch_strip_control'), solo_button='global_solo_button', select_button='select_button', delete_button='delete_button', scroll_page_up_button='octave_up_button', scroll_page_down_button='octave_down_button', quantize_button='quantize_button', duplicate_button='duplicate_button', mute_button='global_mute_button', scroll_up_button=self._with_shift('octave_up_button'), scroll_down_button=self._with_shift('octave_down_button'))

    def _init_slicing_component(self):
        self._slicing_component = SlicedSimplerComponent(is_enabled=False)
        self._slicing_component.layer = Layer(scroll_page_up_button='octave_up_button', scroll_page_down_button='octave_down_button', scroll_up_button=self._with_shift('octave_up_button'), scroll_down_button=self._with_shift('octave_down_button'), delete_button='delete_button', select_button='select_button')

    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 = self._create_note_repeat_layer()
        self._note_repeat_enabler = EnablingModesComponent(name='Note_Repeat_Enabler', component=self._note_repeat, enabled_color='DefaultButton.Alert', disabled_color='DefaultButton.On')
        self._note_repeat_enabler.set_enabled(False)
        self._note_repeat_enabler.layer = Layer(cycle_mode_button='repeat_button')

    def _create_note_repeat_layer(self):
        return Layer(aftertouch_control='aftertouch_control', select_buttons='side_buttons', priority=consts.DIALOG_PRIORITY)

    def _init_notification(self):
        self._notification = self._create_notification_component()

    def _create_notification_component(self):
        raise NotImplementedError

    def _create_message_box_background_layer(self):
        return BackgroundLayer('select_buttons', 'track_state_buttons', 'scale_presets_button', 'octave_up_button', 'octave_down_button', 'side_buttons', 'repeat_button', 'accent_button', 'global_param_controls', 'global_param_touch_buttons', 'touch_strip_control', 'touch_strip_tap', 'matrix', 'nav_up_button', 'nav_down_button', 'nav_left_button', 'nav_right_button', 'shift_button', 'select_button', 'delete_button', 'duplicate_button', 'double_button', 'quantize_button', 'play_button', 'new_button', 'automation_button', 'tap_tempo_button', 'metronome_button', 'fixed_length_button', 'record_button', 'undo_button', 'tempo_control', 'swing_control', 'master_volume_control', 'global_param_controls', 'vol_mix_mode_button', 'pan_send_mix_mode_button', 'single_track_mix_mode_button', 'clip_mode_button', 'device_mode_button', 'browse_mode_button', 'user_button', 'master_select_button', 'create_device_button', 'create_track_button', 'global_track_stop_button', 'global_mute_button', 'global_solo_button', 'note_mode_button', 'session_mode_button', priority=consts.MESSAGE_BOX_PRIORITY)

    def _create_message_box_layer(self):
        raise RuntimeError

    def _init_message_box(self):
        self._dialog = DialogComponent(is_enabled=True, is_root=True)
        self._dialog.message_box_layer = (self._create_message_box_background_layer(), self._create_message_box_layer())

    def _for_non_frozen_tracks(self, component, **k):
        """ Wrap component into a mode that will only enable it when
        the track is not frozen """
        TrackFrozenModesComponent(default_mode=component, frozen_mode=self._track_frozen_info, **k)
        return component

    def _init_undo_redo_actions(self):
        self._undo_redo = UndoRedoComponent(name='Undo_Redo', is_root=True)
        self._undo_redo.layer = Layer(undo_button='undo_button', redo_button=self._with_shift('undo_button'))

    def _init_stop_clips_action(self):
        pass

    def _create_capture_and_insert_scene_component(self):
        return CaptureAndInsertSceneComponent(name='Capture_And_Insert_Scene', is_root=True)

    def _init_duplicate_actions(self):
        capture_element = ChoosingElement(self._settings['workflow'], 'duplicate_button', self._with_shift('duplicate_button'))
        self._capture_and_insert_scene = self._create_capture_and_insert_scene_component()
        self._capture_and_insert_scene.set_enabled(True)
        self._capture_and_insert_scene.layer = Layer(action_button=capture_element)
        duplicate_element = OptionalElement('duplicate_button', self._settings['workflow'], False)
        self._duplicate_detail_clip = DuplicateDetailClipComponent(name='Duplicate_Detail_Clip', is_root=True)
        self._duplicate_detail_clip.set_enabled(True)
        self._duplicate_detail_clip.layer = Layer(action_button=duplicate_element)
        self._duplicate_loop = self._for_non_frozen_tracks(DuplicateLoopComponent(name='Duplicate_Loop', layer=Layer(action_button='double_button'), is_enabled=False), is_root=True)

    def _init_delete_actions(self):
        self._delete_component = DeleteComponent(name='Deleter', is_root=True)
        self._delete_component.layer = Layer(delete_button='delete_button')
        self._delete_default_component = DeleteAndReturnToDefaultComponent(name='DeleteAndDefault', is_root=True)
        self._delete_default_component.layer = Layer(delete_button='delete_button')
        self._delete_clip = DeleteSelectedClipComponent(name='Selected_Clip_Deleter', is_root=True)
        self._delete_clip.layer = Layer(action_button='delete_button')
        self._delete_scene = DeleteSelectedSceneComponent(name='Selected_Scene_Deleter', is_root=True)
        self._delete_scene.layer = Layer(action_button=self._with_shift('delete_button'))

    def _init_quantize_actions(self):
        raise NotImplementedError

    def _init_value_components(self):
        self._swing_amount = ValueComponent('swing_amount', self.song, display_label='Swing Amount:', display_format='%d%%', model_transform=lambda x: clamp(x / 200.0, 0.0, 0.5), view_transform=lambda x: x * 200.0, encoder_factor=100.0, encoder_touch_delay=TEMPO_SWING_TOUCH_DELAY, is_root=True)
        self._swing_amount.layer = Layer(encoder='swing_control')
        self._tempo = ValueComponent('tempo', self.song, display_label='Tempo:', display_format='%0.2f BPM', encoder_factor=128.0, encoder_touch_delay=TEMPO_SWING_TOUCH_DELAY, is_root=True)
        self._tempo.layer = Layer(encoder='tempo_control', shift_button='shift_button')
        self._master_vol = ParameterValueComponent(self.song.master_track.mixer_device.volume, display_label='Master Volume:', display_seg_start=3, name='Master_Volume_Display', is_root=True)
        self._master_vol.layer = Layer(encoder='master_volume_control')
        self._master_cue_vol = ParameterValueComponent(self.song.master_track.mixer_device.cue_volume, display_label='Cue Volume:', display_seg_start=3, name='Cue_Volume_Display', is_root=True)
        self._master_cue_vol.layer = Layer(encoder=self._with_shift('master_volume_control'))

    def _init_m4l_interface(self):
        self._m4l_interface = M4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard, priority=consts.M4L_PRIORITY, is_root=True)
        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

    @listens('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)

    @listens('selected_track.is_frozen')
    def __on_selected_track_is_frozen_changed(self):
        self._select_note_mode()

    def _on_selected_track_changed(self):
        self.reset_controlled_track()
        self._select_note_mode()
        self._note_repeat_enabler.selected_mode = 'disabled'

    def _send_midi(self, midi_event_bytes, optimized = True):
        if not self._suppress_sysex or not midi.is_sysex(midi_event_bytes):
            return super(PushBase, self)._send_midi(midi_event_bytes, optimized)

    def _update_full_velocity(self, accent_is_active):
        self._drum_step_sequencer.full_velocity = accent_is_active
        self._instrument.full_velocity = accent_is_active

    def _update_playhead_color(self, color):
        self._instrument.playhead_color = color
        self._drum_step_sequencer.playhead_color = color

    @listens('session_record')
    def __on_session_record_changed(self):
        status = self.song.session_record
        self._update_playhead_color('PlayheadRecord' if status else 'Playhead')
        feedback_color = int(to_midi_value(self._skin['Instrument.FeedbackRecord']) if status else to_midi_value(self._skin['Instrument.Feedback']))
        self._c_instance.set_feedback_velocity(feedback_color)

    @listens('selected_mode')
    def __on_accent_mode_changed(self, mode_name):
        accent_is_active = mode_name == 'enabled'
        self._update_full_velocity(accent_is_active)

    @listens('enabled')
    def __on_fixed_length_enabled_changed(self, enabled):
        self.preferences['fixed_length_enabled'] = enabled

    @listens('selected_index')
    def __on_fixed_length_selected_index_changed(self, index):
        self.preferences['fixed_length_option'] = index

    @listens('before_mode_sent')
    def __on_before_hardware_mode_sent(self, mode):
        self._suppress_sysex = False

    @listens('after_mode_sent')
    def __on_after_hardware_mode_sent(self, mode):
        if mode == sysex.USER_MODE:
            self._suppress_sysex = True

    @listens('mode')
    def __on_hardware_mode_changed(self, mode):
        if mode == sysex.USER_MODE:
            self._suppress_sysex = True
        self._update_auto_arm()

    @listens('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(self._user.mode == sysex.LIVE_MODE and (selected_mode or self._matrix_modes.selected_mode) == 'note')

    @listens('instrument')
    def __on_percussion_instrument_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, sliced_simpler = self._percussion_instruments_for_track(track)
        self._drum_component.set_drum_group_device(drum_device)
        self._slicing_component.set_simpler(sliced_simpler)
        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'
        elif sliced_simpler:
            self._note_modes.selected_mode = 'slicing'
        else:
            self._note_modes.selected_mode = 'instrument'
        self.reset_controlled_track()

    def _percussion_instruments_for_track(self, track):
        self._percussion_instrument_finder.device_parent = track
        drum_device = self._percussion_instrument_finder.drum_group
        sliced_simpler = self._percussion_instrument_finder.sliced_simpler
        return (drum_device, sliced_simpler)

    def _setup_accidental_touch_prevention(self):
        self._accidental_touch_prevention_layer = BackgroundLayer('tempo_control_tap', 'swing_control_tap', 'master_volume_control_tap', priority=consts.MOMENTARY_DIALOG_PRIORITY)
        self.__on_param_encoder_touched.replace_subjects(self.elements.global_param_touch_buttons_raw)

    @listens_group('value')
    def __on_param_encoder_touched(self, value, encoder):
        """
        When using the parameter encoders, other encoders around it are often accidentally
        touched and will take over the screen.
        By stealing the touch buttons from the encoders, we ensure they are not triggered
        while using any of the parameter encoders.
        """
        if any(imap(lambda e: e.is_pressed(), self.elements.global_param_touch_buttons_raw)):
            self._accidental_touch_prevention_layer.grab(self)
        else:
            self._accidental_touch_prevention_layer.release(self)

    def get_matrix_button(self, column, row):
        return self.elements.matrix_rows_raw[7 - row][column]

    def expect_dialog(self, message):
        self.schedule_message(1, partial(self._dialog.expect_dialog, message))

    def show_notification(self, message, blink_text = None, notification_time = None):
        return self._notification.show_notification(message, blink_text, notification_time)

    def process_midi_bytes(self, midi_bytes, midi_processor):
        if not midi.is_sysex(midi_bytes):
            recipient = self.get_recipient_for_nonsysex_midi_message(midi_bytes)
            if isinstance(recipient, ButtonElement) and midi.extract_value(midi_bytes) != 0 and self._notification is not None:
                self._notification.hide_notification()
        super(PushBase, self).process_midi_bytes(midi_bytes, midi_processor)
Example #19
0
class Cntrlr(LividControlSurface):
	__module__ = __name__
	__doc__ = " Monomodular controller script for Livid CNTRLR "


	_sysex_id = 8
	_model_name = 'Cntrlr'
	_host_name = 'Cntrlr'
	_version_check = 'b996'
	monomodular = None
	device_provider_class = ModDeviceProvider


	def __init__(self, *a, **k):
		super(Cntrlr, self).__init__(*a, **k)
		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_background()
			self._setup_translations()
			#self._setup_autoarm()
			self._setup_session_control()
			self._setup_send_reset_controls()
			self._setup_mixer_control()
			self._setup_transport_control()
			self._setup_device_control()
			self._setup_mod_device_control()
			self._setup_device_selector()
			#self._setup_session_recording_component()
			#self._setup_viewcontrol()
			#self._setup_instrument()
			self._setup_mod()
			self._setup_modswitcher()
			self._setup_translations()
			self._setup_modes()
			self._setup_m4l_interface()
			self._on_device_changed.subject = self.song
			#self.set_feedback_channels(range(14, 15))


	def _initialize_script(self):
		super(Cntrlr, self)._initialize_script()
		self._connected = True
		self._main_modes.selected_mode = 'MixMode'
		self._main_modes.set_enabled(True)
		#self._instrument.set_enabled(True)
		#self._main_modes.selected_mode = 'disabled'
		#self._main_modes.selected_mode = 'MixMode'
		self._session_ring._update_highlight()
		self._session_ring.track_offset = 0
		if liveobj_valid(self.song.visible_tracks[0]):
			self.song.view.selected_track = self.song.visible_tracks[0]


	def _initialize_hardware(self):
		super(Cntrlr, self)._initialize_hardware()
		for index in range(4):
			self._encoder[index].send_value(0)


	def port_settings_changed(self):
		self._main_modes.selected_mode = 'disabled'
		super(Cntrlr, self).port_settings_changed()


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


	def _setup_controls(self):
		is_momentary = True
		optimized = True
		resource = PrioritizedResource
		self._fader = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_FADERS[index], name = 'Fader_' + str(index), num = index, script = self,  optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(8)]
		self._dial_left = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_KNOBS_LEFT[index], name = 'Dial_Left_' + str(index), num = CNTRLR_KNOBS_LEFT[index], script = self, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)]
		self._dial_right = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_KNOBS_RIGHT[index], name = 'Dial_Right_' + str(index), num = CNTRLR_KNOBS_RIGHT[index], script = self, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)]
		self._encoder = [CodecEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CNTRLR_DIALS[index], name = 'Encoder_' + str(index), num = CNTRLR_DIALS[index], script = self, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)]
		self._encoder_button = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CNTRLR_DIAL_BUTTONS[index], name = 'Encoder_Button_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(12)]
		self._grid = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CNTRLR_GRID[index], name = 'Grid_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) for index in range(16)]
		self._button = [MonoButtonElement(is_momentary = is_momentary,msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = CNTRLR_BUTTONS[index], name = 'Button_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource, monobridge = self._monobridge) 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._grid + self._button


	def _setup_background(self):
		self._background = BackgroundComponent(name = 'Background')
		self._background.layer = Layer(priority = 3, matrix = self._matrix.submatrix[:,:], faders = self._fader_matrix.submatrix[:,:], left_knobs = self._knob_left_matrix.submatrix[:,:], right_knobs = self._knob_right_matrix.submatrix[:,:], dials = self._dial_matrix, dial_buttons = self._dial_button_matrix.submatrix[:,:], keys = self._key_matrix.submatrix[:,:])
		self._background.set_enabled(True)


	def _define_sysex(self):
		self.encoder_navigation_on = SendLividSysexMode(livid_settings = self._livid_settings, call = 'set_encoder_encosion_mode', message = [0, 0, 0, 0])


	def _setup_transport_control(self):
		self._transport = CntrlrTransportComponent(name = 'Transport')
		self._transport._play_toggle.view_transform = lambda value: 'Transport.PlayOn' if value else 'Transport.PlayOff'
		self._transport._record_toggle.view_transform = lambda value: 'Transport.RecordOn' if value else 'Transport.RecordOff'
		self._transport.layer = Layer(priority = 4,
									play_button = self._button[28],
									stop_button = self._button[29],
									record_button = self._button[30])
		self._transport.set_enabled(False)


	def _setup_autoarm(self):
		self._auto_arm = CntrlrAutoArmComponent(name='Auto_Arm')
		#self._auto_arm._update_notification = lambda a: None
		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 = FixedLengthSessionRecordingComponent(clip_creator = self._clip_creator, view_controller = ViewControlComponent(), name = 'SessionRecorder') # is_enabled = False)
		self._recorder.main_layer = AddLayerMode(self._recorder, Layer(priority = 4, record_button = self._button[29]))
		self._recorder.shift_layer = AddLayerMode(self._recorder, Layer(priority = 4, automation_button = self._button[29]))
		self._recorder.set_enabled(False)


	def _setup_session_control(self):
		self._session_ring = SessionRingComponent(num_tracks = 4, num_scenes = 4)
		self._session_ring.set_enabled(False)

		self._session_navigation = CntrlrSessionNavigationComponent(name = 'SessionNavigation', session_ring = self._session_ring)

		self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'

		self._session_navigation.layer = Layer(priority = 4,
									down_button = self._button[14],
									up_button = self._button[15],
									left_button = self._button[12],
									right_button = self._button[13])

		self._session_navigation.set_enabled(False)

		self._session = SessionComponent(session_ring = self._session_ring, auto_name = True)
		hasattr(self._session, '_enable_skinning') and self._session._enable_skinning()

		self._session.layer = Layer(priority = 4, clip_launch_buttons = self._matrix.submatrix[:,:])
		self._session.set_enabled(False)

		self._session_zoom = SessionOverviewComponent(name = 'SessionZoom', session_ring = self._session_ring, enable_skinning = True)
		self._session_zoom.layer = Layer(priority = 4, button_matrix = self._matrix.submatrix[:,:])
		self._session_zoom.set_enabled(False)


	def _setup_send_reset_controls(self):
		self._send_reset = ResetSendsComponent(script = self)
		self._send_reset.layer = Layer(priority = 4, buttons = self._key_matrix.submatrix[8:12, :1])
		self._send_reset.set_enabled(False)


	def _setup_mixer_control(self):
		self._mixer = MonoMixerComponent(name = 'Mixer', num_returns = 2,tracks_provider = self._session_ring, track_assigner = SimpleTrackAssigner(), invert_mute_feedback = True, auto_name = True, enable_skinning = True)
		self._mixer.fader_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],
											send_controls = self._knob_left_matrix,
											eq_gain_controls = self._knob_right_matrix))
		self._mixer.button_layer = AddLayerMode(self._mixer, Layer(priority = 4, mute_buttons = self._key_matrix.submatrix[:4, 1:],
											stop_clip_buttons = self._key_matrix.submatrix[8:12, 1:],
											solo_buttons = self._key_matrix.submatrix[:4, :1],
											arm_buttons = self._key_matrix.submatrix[4:8, :1],
											track_select_buttons = self._key_matrix.submatrix[4:8, 1:],))
		self._mixer.master_strip().layer = Layer(priority = 4, volume_control = self._fader[7],)

		self._mixer.set_enabled(False)


	def _setup_device_control(self):
		self._device_selection_follows_track_selection = FOLLOW
		self._device = CntrlrDeviceComponent(script = self, name = 'Device_Component', device_provider = self._device_provider, device_bank_registry = DeviceBankRegistry())
		self._device.layer = Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:, 1:],
													on_off_button = self._encoder_button[4],
													bank_prev_button = self._encoder_button[8],
													bank_next_button = self._encoder_button[9],)
													#lock_button = self._encoder_button[7])
		self._device.set_enabled(False)

		self._device_navigator = DeviceNavigator(self._device_provider, self._mixer, self)
		self._device_navigator.name = 'Device_Navigator'
		self._device_navigator.layer = Layer(priority = 4,
											prev_button = self._encoder_button[10],
											next_button = self._encoder_button[11],)
		self._device_navigator.set_enabled(False)


	def _setup_mod_device_control(self):
		self._mod_device = SpecialCntrlrDeviceComponent(script = self, name = 'Device_Component', device_provider = self._device_provider, device_bank_registry = DeviceBankRegistry())
		self._mod_device.layer = Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:, :],)
		self._mod_device.set_enabled(False)


	def _setup_device_selector(self):
		self._device_selector = CntrlrDeviceSelector(self)
		self._device_selector.name = 'Device_Selector'
		#self._device_selector.select_layer = AddLayerMode(self._device_selector, Layer(priority = 6 , matrix = self._matrix.submatrix[:, :]))
		#self._device_selector.select_layer = AddLayerMode(self._device_selector, Layer(priority = 6, matrix = ButtonMatrixElement(rows = [self._grid[:4],self._grid[4:8],self._grid[8:12],self._grid[12:14]])))
		#self._device_selector.assign_layer = AddLayerMode(self._device_selector, Layer(priority = 7, assign_button = self._grid[14]))
		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._color = 127
		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, device_provider = self._device_provider) # is_enabled = False)
		self.modhandler.name = 'ModHandler'
		self.modhandler.lock_layer = AddLayerMode(self.modhandler, Layer(priority=8, lock_button=self._grid[15]))
		self.modhandler.layer = Layer(priority = 8,
										cntrlr_encoder_button_grid = self._dial_button_matrix.submatrix[:,:],
										cntrlr_grid = self._matrix.submatrix[:,:],
										cntrlr_keys = self._key_matrix.submatrix[:,:],)
										#parameter_controls = self._dial_matrix.submatrix[:,:])
		self.modhandler.set_enabled(False)


	def _setup_modswitcher(self):
		self._modswitcher = ModesComponent(name = 'ModSwitcher')  # is_enabled = False)
		self._modswitcher.set_enabled(False)


	def _setup_viewcontrol(self):
		self._view_control = CntrlrViewControlComponent(name='View_Control')
		self._view_control.main_layer = AddLayerMode(self._view_control, Layer(scene_select_dial = self._encoder[2],
																				track_select_dial = self._encoder[3],))
		#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)


	def _setup_modes(self):

		self._modswitcher = ModesComponent(name = 'ModSwitcher')
		self._modswitcher.add_mode('mod', [self._mixer,
													self._mixer.fader_layer,
													self.modhandler,
													self._mod_device,
													self._device_selector,])
		self._modswitcher.add_mode('translations', [self._translations,
													self._device,
													self._mixer,
													self._mixer.fader_layer,
													self._device_navigator,
													self._device_selector])
		self._modswitcher.selected_mode = 'translations'
		self._modswitcher.set_enabled(False)

		self._session_modes = ModesComponent(name = 'SessionModes')
		self._session_modes.add_mode('Launch', [self._session])
		self._session_modes.add_mode('Zoom', [self._session_zoom])
		self._session_modes.layer = Layer(priority = 4, cycle_mode_button = self._button[31])
		self._session_modes.set_enabled(False)

		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('disabled', [self._background, self.encoder_navigation_on])
		self._main_modes.add_mode('MixMode', [self._mixer,
													self._mixer.fader_layer,
													self._mixer.button_layer,
													self._session_modes,
													self._session_navigation,
													self._session_ring,
													self._device,
													self._device_navigator,
													self._send_reset,
													self._transport])

		self._main_modes.add_mode('ModMode1', [self._modswitcher,
													self._choose_mod,
													DelayMode(self._update_modswitcher, delay = .1, parent_task_group = self._task_group),
													DelayMode(self.modhandler.update, delay = .2, parent_task_group = self._task_group)],
													behaviour = DefaultedBehaviour(default_mode = 'MixMode'))
		self._main_modes.add_mode('ModMode2', [self._modswitcher,
													self._choose_mod,
													DelayMode(self._update_modswitcher, delay = .1, parent_task_group = self._task_group),
													DelayMode(self.modhandler.update, delay = .2, parent_task_group = self._task_group)],
													behaviour = DefaultedBehaviour(default_mode = 'MixMode'))
		self._main_modes.add_mode('ModMode3', [self._modswitcher,
													self._choose_mod,
													DelayMode(self._update_modswitcher, delay = .1, parent_task_group = self._task_group),
													DelayMode(self.modhandler.update, delay = .2, parent_task_group = self._task_group)],
													behaviour = DefaultedBehaviour(default_mode = 'MixMode'))
		self._main_modes.add_mode('ModMode4', [self._modswitcher,
													self._choose_mod,
													DelayMode(self._update_modswitcher, delay = .1, parent_task_group = self._task_group),
													DelayMode(self.modhandler.update, delay = .2, parent_task_group = self._task_group)],
													behaviour = DefaultedBehaviour(default_mode = 'MixMode'))

		self._main_modes.layer = Layer(priority = 4, ModMode1_button = self._encoder_button[0], ModMode2_button = self._encoder_button[1], ModMode3_button = self._encoder_button[2], ModMode4_button = self._encoder_button[3]) #,
		self._main_modes.selected_mode = 'disabled'
		self._main_modes.set_enabled(True)


	def _choose_mod(self):
		modes = ('ModMode1', 'ModMode2', 'ModMode3', 'ModMode4')
		mode = self._main_modes.selected_mode
		debug('choose_mod:', self._main_modes.selected_mode)
		if mode in modes:
			index = modes.index(mode)
			self._translations._channel = index + self._translations._user_channel_offset
			self._translations.update()
			self._device_selector.select_device(index)


	def _setup_m4l_interface(self):
		self._m4l_interface = M4LInterfaceComponent(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')


	@listens('appointed_device')
	def _on_device_changed(self):
		debug('appointed device changed, script')
		#self._main_modes.selected_mode is 'ModSwitcher' and self._update_modswitcher()


	def _on_selected_track_changed(self):
		super(Cntrlr, self)._on_selected_track_changed()
		#self._drum_group_finder.device_parent = self.song.veiw.selected_track
		#if not len(self.song.view.selected_track.devices):
		#	self._main_modes.selected_mode is 'ModSwitcher' and self._update_modswitcher()


	def _update_modswitcher(self):
		debug('update modswitcher', self.modhandler.active_mod())
		if self.modhandler.active_mod() and self._device_selector.has_mod_entry(['ModMode1', 'ModMode2', 'ModMode3', 'ModMode4'].index(self._main_modes.selected_mode)):
			self._modswitcher.selected_mode = 'mod'
		else:
			self._modswitcher.selected_mode = 'translations'


	def update_display(self):
		super(Cntrlr, self).update_display()
		self.modhandler.send_ring_leds()


	def restart_monomodular(self):
		#debug('restart monomodular')
		self.modhandler.disconnect()
		with self.component_guard():
			self._setup_mod()
Example #20
0
class OhmModesRay(OhmModes):


	_sysex_id = 2
	_alt_sysex_id = 7
	_model_name = 'Ohm'
	_version_check = 'b996'
	_host_name = 'Ohm'
	device_provider_class = ModDeviceProvider

	def __init__(self, c_instance):
		super(OhmModes, self).__init__(c_instance)
		self._skin = Skin(OhmColors)
		with self.component_guard():
			self._define_sysex()
			self._setup_controls()
			self._setup_background()
			self._setup_m4l_interface()
			#self._setup_translations()
			self._setup_session_control()
			self._setup_mixer_control()
			self._setup_instrument()
			#self._setup_device_control()
			#self._setup_transport_control()
			#self._setup_drumgroup()
			#self._setup_keygroup()
			#self._setup_bassgroup()
			#self._setup_mod()
			#self._setup_modswitcher()
			self._setup_modes()
		self._on_device_changed.subject = self._device_provider
		self.set_feedback_channels(FEEDBACK_CHANNELS)
		self._session_ring._update_highlight()


	def set_feedback_channels(self, channels, *a, **k):
		super(OhmModes, self).set_feedback_channels(channels, *a, **k)



	def _setup_session_control(self):
		self._session_ring = SessionRingComponent(num_tracks = 7, num_scenes = 7)
		self._session_ring.set_enabled(True)

		self._session_navigation = SessionNavigationComponent(session_ring = self._session_ring)
		self._session_navigation.scroll_navigation_layer = AddLayerMode(self._session_navigation, Layer(priority = 5, up_button = self._menu[1], down_button = self._menu[4], left_button = self._menu[3], right_button = self._menu[5]))
		self._session_navigation.page_navigation_layer = AddLayerMode(self._session_navigation, Layer(priority = 5, page_up_button = self._menu[2], page_down_button = self._menu[5], page_left_button = self._menu[3], page_right_button = self._menu[4]))
		self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation.set_enabled(False)

		self._session = SpecialOhmSessionComponent(name = 'Session', session_ring = self._session_ring, auto_name = True)
		self._session.set_enabled(False)
		self._session.clip_launch_layer = AddLayerMode(self._session, Layer(priority = 5,  clip_launch_buttons = self._matrix.submatrix[:7,:7]))
		self._session.scene_launch_layer = AddLayerMode(self._session, Layer(priority = 5,  scene_launch_buttons = self._matrix.submatrix[7,:7]))
		self._session.stop_clips_layer = AddLayerMode(self._session, Layer(priority = 5,  stop_track_clip_buttons = self._matrix.submatrix[:7,7], stop_all_clips_button = self._grid[7][7]))

		"""self._session_zoom = SessionOverviewComponent(name = 'Session_Overview', session_ring = self._session_ring, enable_skinning = True)
		self._session_zoom.layer = Layer(priority = 5, button_matrix = self._matrix.submatrix[:7,:7])
		self._session_zoom.set_enabled(False)

		self._session_modes = ModesComponent(name = 'Session_Modes')
		self._session_modes.add_mode('disabled', [self._session,
														self._session.clip_launch_layer,
														self._session.scene_launch_layer,
														self._session_navigation,
														self._session_navigation.scroll_navigation_layer])
		self._session_modes.add_mode('enabled', [self._session,
														self._session.scene_launch_layer,
														self._session_zoom,
														self._session_navigation,
														self._session_navigation.page_navigation_layer],
														behaviour = DefaultedBehaviour())
		self._session_modes.layer = Layer(priority = 5, enabled_button = self._grid[7][7])
		self._session_modes.selected_mode = 'disabled'
		self._session_modes.set_enabled(False)"""



	def _setup_mixer_control(self):
		self._mixer = OhmMixerComponent(name = 'Mixer', tracks_provider = self._session_ring, track_assigner = SimpleTrackAssigner(), invert_mute_feedback = True, auto_name = True, enable_skinning = True)
		#self._mixer.layer = Layer(priority = 5, volume_controls = self._fader_matrix.submatrix[:7, :], prehear_volume_control = self._dial[15], crossfader_control = self._crossfader)
		self._mixer.layer = Layer(priority = 5, solo_buttons = self._button_matrix.submatrix[:7,:])
		"""self._mixer.master_strip().layer = Layer(priority = 5, volume_control = self._fader[7], select_button = self._button[7])
		self._mixer.mix_layer = AddLayerMode(self._mixer, Layer(priority = 5, mute_buttons = self._matrix.submatrix[:7,5],
													solo_buttons = self._matrix.submatrix[:7,6],
													arm_buttons = self._matrix.submatrix[:7,7],
													send_controls = self._dial_matrix.submatrix[:,:2],
													pan_controls = self._dial_matrix.submatrix[:7,2:],
													track_select_buttons = self._button_matrix.submatrix[:7,:],))
		self._mixer.dj_layer = AddLayerMode(self._mixer, Layer(priority = 5, mute_buttons = self._matrix.submatrix[:7,5],
													crossfade_toggles = self._matrix.submatrix[:7,6],
													end_pan_controls = self._dial_matrix.submatrix[:3,3],
													eq_gain_controls = self._dial_matrix.submatrix[:,:3],
													track_select_buttons = self._button_matrix.submatrix[:7,:],))
		self._mixer.instrument_layer = AddLayerMode(self._mixer, Layer(priority = 5,
													instrument_send_controls = self._dial_matrix.submatrix[:,2:],
													arming_track_select_buttons = self._button_matrix.submatrix[:7,:]))
		"""


	def _setup_instrument(self):
		self._grid_resolution = GridResolution()

		self._c_instance.playhead.enabled = True
		self._playhead_element = PlayheadElement(self._c_instance.playhead)
		#self._playhead_element.reset()

		#quantgrid = ButtonMatrixElement([self._base_grid._orig_buttons[2][4:8], self._base_grid._orig_buttons[3][4:7]])

		self._drum_group_finder = PercussionInstrumentFinder(device_parent=self.song.view.selected_track)

		self._instrument = OhmMonoInstrumentComponent(name = 'InstrumentModes', script = self, skin = self._skin, drum_group_finder = self._drum_group_finder, grid_resolution = self._grid_resolution, settings = DEFAULT_INSTRUMENT_SETTINGS, device_provider = self._device_provider, parent_task_group = self._task_group)
		self._instrument.layer = Layer(priority = 5, shift_button = self._livid)
		self._instrument.audioloop_layer = LayerMode(self._instrument, Layer(priority = 5, loop_selector_matrix = self._matrix))

		self._instrument.keypad_options_layer = AddLayerMode(self._instrument, Layer(priority = 5,
									scale_up_button = self._menu[0],
									scale_down_button = self._menu[3],
									offset_up_button = self._menu[1],
									offset_down_button = self._menu[4],
									vertical_offset_up_button = self._menu[2],
									vertical_offset_down_button = self._menu[5],))
		self._instrument.drumpad_options_layer = AddLayerMode(self._instrument, Layer(priority = 5,
									scale_up_button = self._menu[0],
									scale_down_button = self._menu[3],
									drum_offset_up_button = self._menu[1],
									drum_offset_down_button = self._menu[4],
									drumpad_mute_button = self._menu[2],
									drumpad_solo_button = self._menu[5],))

		self._instrument._keypad.octave_toggle_layer = AddLayerMode(self._instrument._keypad, Layer(priority = 5)) #, offset_shift_toggle = self._livid))
		self._instrument._drumpad.octave_toggle_layer = AddLayerMode(self._instrument._drumpad, Layer(priority = 5)) #, offset_shift_toggle = self._livid))

		self._instrument._keypad.main_layer = LayerMode(self._instrument._keypad, Layer(priority = 5, keypad_matrix = self._matrix.submatrix[:,:]))
		self._instrument._keypad.select_layer = LayerMode(self._instrument._keypad, Layer(priority = 5, keypad_select_matrix = self._matrix.submatrix[:, :]))
		self._instrument._keypad.split_layer = LayerMode(self._instrument._keypad, Layer(priority = 5, keypad_matrix = self._matrix.submatrix[:, 2:4]))
		self._instrument._keypad.split_select_layer = LayerMode(self._instrument._keypad, Layer(priority = 5, keypad_select_matrix = self._matrix.submatrix[:, 2:4]))

		self._instrument._keypad.sequencer_layer = AddLayerMode(self._instrument._keypad, Layer(priority = 5, playhead = self._playhead_element, sequencer_matrix = self._matrix.submatrix[:, :4]))
		self._instrument._keypad.sequencer_shift_layer = AddLayerMode(self._instrument._keypad, Layer(priority = 5, loop_selector_matrix = self._matrix.submatrix[:, :4], quantization_buttons = self._matrix.submatrix[:8, 1:2],)) #follow_button = self._pad[15]))

		self._instrument._drumpad.main_layer = LayerMode(self._instrument._drumpad, Layer(priority = 5, drumpad_matrix = self._matrix.submatrix[:,4:], sequencer_matrix = self._matrix.submatrix[:, :2], loop_selector_matrix = self._matrix.submatrix[:, 3:4], playhead = self._playhead_element, quantization_buttons = self._matrix.submatrix[:, 2:3]))
		self._instrument._drumpad.select_layer = LayerMode(self._instrument._drumpad, Layer(priority = 5, drumpad_select_matrix = self._matrix.submatrix[:,4:],  sequencer_matrix = self._matrix.submatrix[:, :2], loop_selector_matrix = self._matrix.submatrix[:, 3:4], playhead = self._playhead_element, quantization_buttons = self._matrix.submatrix[:, 2:3]))
		self._instrument._drumpad.split_layer = LayerMode(self._instrument._drumpad, Layer(priority = 5, drumpad_matrix = self._matrix.submatrix[:4, 4:],))
		self._instrument._drumpad.split_select_layer = LayerMode(self._instrument._drumpad, Layer(priority = 5, drumpad_select_matrix = self._matrix.submatrix[:4,4:]))

		self._instrument._drumpad.sequencer_layer = AddLayerMode(self._instrument._drumpad, Layer(priority = 5, playhead = self._playhead_element, sequencer_matrix = self._matrix.submatrix[:, :4]))
		self._instrument._drumpad.sequencer_shift_layer = AddLayerMode(self._instrument._drumpad, Layer(priority = 5, loop_selector_matrix = self._matrix.submatrix[4:8, :2], quantization_buttons = self._matrix.submatrix[4:8, 2:],)) #follow_button = self._pad[31]))

		self._instrument._selected_session._keys_layer = LayerMode(self._instrument._selected_session, Layer(priority = 5, clip_launch_buttons = self._matrix.submatrix[:, :2]))
		self._instrument._selected_session._drum_layer = LayerMode(self._instrument._selected_session, Layer(priority = 5, clip_launch_buttons = self._matrix.submatrix[4:8, :]))

		self._instrument._main_modes = ModesComponent(parent = self._instrument, name = 'InstrumentModes')
		self._instrument._main_modes.add_mode('disabled', [])
		self._instrument._main_modes.add_mode('drumpad', [self._instrument._drumpad, self._instrument._drumpad.main_layer, self._instrument.drumpad_options_layer])
		self._instrument._main_modes.add_mode('drumpad_split', [self._instrument._drumpad, self._instrument._drumpad.split_layer, self._instrument._selected_session, self._instrument._selected_session._drum_layer])
		self._instrument._main_modes.add_mode('drumpad_sequencer', [self._instrument._drumpad, self._instrument._drumpad.sequencer_layer, self._instrument._drumpad.split_layer])
		self._instrument._main_modes.add_mode('drumpad_shifted', [self._instrument._drumpad, self._instrument._drumpad.select_layer, self._instrument.drumpad_options_layer, self._instrument._drumpad.octave_toggle_layer])
		self._instrument._main_modes.add_mode('drumpad_split_shifted', [ self._instrument._drumpad, self._instrument._drumpad.split_select_layer, self._instrument.drumpad_options_layer, self._instrument._drumpad.octave_toggle_layer, self._instrument._selected_session, self._instrument._selected_session._drum_layer])
		self._instrument._main_modes.add_mode('drumpad_sequencer_shifted', [self._instrument._drumpad, self._instrument._drumpad.split_select_layer, self._instrument._drumpad.sequencer_shift_layer, self._instrument.drumpad_options_layer, self._instrument._drumpad.octave_toggle_layer])
		self._instrument._main_modes.add_mode('keypad', [self._instrument._keypad, self._instrument._keypad.main_layer, self._instrument.keypad_options_layer])
		self._instrument._main_modes.add_mode('keypad_split', [self._instrument._keypad, self._instrument._keypad.split_layer, self._instrument._selected_session, self._instrument._selected_session._keys_layer])
		self._instrument._main_modes.add_mode('keypad_sequencer', [self._instrument._keypad, self._instrument._keypad.sequencer_layer, self._instrument._keypad.split_layer], )
		self._instrument._main_modes.add_mode('keypad_shifted', [self._instrument._keypad, self._instrument._keypad.select_layer, self._instrument.keypad_options_layer, self._instrument._keypad.octave_toggle_layer])
		self._instrument._main_modes.add_mode('keypad_split_shifted', [self._instrument._keypad, self._instrument._keypad.split_select_layer, self._instrument.keypad_options_layer, self._instrument._keypad.octave_toggle_layer, self._instrument._selected_session, self._instrument._selected_session._keys_layer])
		self._instrument._main_modes.add_mode('keypad_sequencer_shifted', [self._instrument._keypad, self._instrument._keypad.split_select_layer, self._instrument._keypad.sequencer_shift_layer, self._instrument.keypad_options_layer, self._instrument._keypad.octave_toggle_layer])
		self._instrument._main_modes.add_mode('audioloop', [self._instrument.audioloop_layer])
		#self._instrument.register_component(self._instrument._main_modes)
		self._instrument.set_enabled(False)




	def _setup_modes(self):

		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('disabled', [self._background])
		self._main_modes.add_mode('Mix', [self._mixer, self._session, self._session.stop_clips_layer, self._session.clip_launch_layer, self._session.scene_launch_layer, self._session_navigation, self._session_navigation.scroll_navigation_layer])
		self._main_modes.add_mode('Instrument', [self._instrument])
		self._main_modes.selected_mode = 'disabled'
		self._main_modes.layer = Layer(priority = 5, Mix_button = self._shift_l, Instrument_button = self._shift_r)
		self._main_modes.set_enabled(True)


	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(OhmModes, self).set_controlled_track(track)
		else:
			self.release_controlled_track()

	@listens('device')
	def _on_device_changed(self):
		debug('_on_device_changed')
		self.update()

	def update(self):
		self.reset_controlled_track()
		self.set_feedback_channels(FEEDBACK_CHANNELS)
		super(OhmModes, self).update()
Example #21
0
class Cntrlr(BaseCntrlr):


	def __init__(self, *a, **k):
		super(Cntrlr, self).__init__(*a, **k)
		self._skin = Skin(CntrlrColors)
		for button in self._grid:
			button._skin = self._skin
	

	def _open_log(self):
		self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) + " for Georg Oswald " + str(self._version_check) + " log opened =>>>>>>>>>>>>>>>>>>>") 
		self.show_message(str(self._host_name) + ' Control Surface Loaded')
	

	def _setup_transport_control(self):
		super(Cntrlr, self)._setup_transport_control()
		self._transport._overdub_toggle.view_transform = lambda value: 'Transport.OverdubOn' if value else 'Transport.OverdubOff'
		self._transport.layer = Layer(priority = 4,
									play_button = self._button[24])
		self._transport.overdub_layer = AddLayerMode(self._transport, Layer(priority = 4,
									overdub_button = self._button[25]))
	

	def _setup_session_control(self):
		super(Cntrlr, self)._setup_session_control()
		self._session_navigation.nav_layer = AddLayerMode(self._session_navigation, Layer(priority = 4,
									page_down_button = self._button[22],
									page_up_button = self._button[23],
									page_left_button = self._button[20],
									page_right_button = self._button[21]))
		self._session.stop_clips_layer = AddLayerMode(self._session, Layer(priority = 4,
									stop_all_clips_button = self._button[29],))
	

	def _setup_session_recording_component(self):
		super(Cntrlr, self)._setup_session_recording_component()
		self._recorder.main_layer = AddLayerMode(self._recorder, Layer(priority = 4))
		self._recorder.shift_layer = AddLayerMode(self._recorder, Layer(priority = 4, automation_button = self._button[25]))
	

	def _setup_mixer_control(self):
		super(Cntrlr, self)._setup_mixer_control()

		mute_buttons = ButtonMatrixElement(name = 'mute_buttons', rows = [self._button[:4] + self._button[12:16]])
		select_buttons = ButtonMatrixElement(name = 'select_buttons', rows = [self._button[16:20] + self._button[28:32]])

		self._G_session_ring = SessionRingComponent(num_tracks = 8, num_scenes = 4)
		self._G_session_ring.set_enabled(False)

		self._G_mixer = MonoMixerComponent(name = 'Mixer', num_returns = 4,tracks_provider = self._G_session_ring, track_assigner = simple_track_assigner, invert_mute_feedback = True, auto_name = True, enable_skinning = True)

		if FREE_ENCODER_IS_CROSSFADER:
			self._mixer.layer = Layer(priority = 4, crossfader_control = self._encoder[1])
		#self._G_mixer.select_dial_layer = AddLayerMode(self._G_mixer, Layer(priority = 5, 
		#									track_select_dial = self._encoder[3],))
		self._G_mixer.main_faders_layer = AddLayerMode(self._G_mixer, Layer(priority = 4,
											volume_controls = self._fader_matrix.submatrix[:8, :],))
		self._G_mixer.main_buttons_layer = AddLayerMode(self._G_mixer, Layer(priority = 4,
											mute_buttons = mute_buttons,
											arming_track_select_buttons = select_buttons,
											solo_buttons = self._key_matrix.submatrix[4:12, :1],))
		self._G_mixer.shifted_buttons_layer = AddLayerMode(self._G_mixer, Layer(priority = 4,
											mute_buttons = mute_buttons,))
		self._G_mixer.solo_buttons_layer = AddLayerMode(self._G_mixer, Layer(priority = 4,
											solo_buttons = self._key_matrix.submatrix[4:12, :1],))
		self._G_mixer.mute_buttons_layer = AddLayerMode(self._G_mixer, Layer(priority = 4,
											mute_buttons = mute_buttons,))

		self._G_mixer.stop_layer = AddLayerMode(self._G_mixer, Layer(priority = 4,
											stop_clip_buttons = self._key_matrix.submatrix[8:12, 1:],))

		self._G_mixer.main_knobs_layer = AddLayerMode(self._G_mixer, Layer(priority = 4))

		self._G_mixer.master_fader_layer = AddLayerMode(self._G_mixer.master_strip(), Layer(priority = 4,))
		self._G_mixer.instrument_buttons_layer = AddLayerMode(self._G_mixer, Layer(priority = 4,
											mute_buttons = mute_buttons,
											track_select_buttons = select_buttons,))
		self._G_mixer.set_enabled(False)
	

	def _setup_device_control(self):
		super(Cntrlr, self)._setup_device_control()
		self._device_navigator.main_layer = AddLayerMode(self._device_navigator, Layer(priority = 4,
											prev_button = self._encoder_button[8], 
											next_button = self._encoder_button[9], 
											exit_button = self._encoder_button[10], 
											enter_button = self._encoder_button[11],))
	

	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._drum_group_finder = PercussionInstrumentFinder(device_parent=self.song.view.selected_track)

		self._instrument = CntrlrMonoInstrumentComponent(name = 'InstrumentComponent', is_enabled = True, script = self, skin = self._skin, grid_resolution = self._grid_resolution, drum_group_finder = self._drum_group_finder, parent_task_group = self._task_group, settings = DEFAULT_INSTRUMENT_SETTINGS, device_provider = self._device_provider)
		self._instrument.shift_button_layer = AddLayerMode(self._instrument, Layer(priority = 5, session_mode_button = self._button[26], shift_mode_button = self._button[27]))
		self._instrument.audioloop_layer = AddLayerMode(self._instrument, Layer(priority = 5))

		self._instrument.keypad_shift_layer = AddLayerMode(self._instrument, Layer(priority = 5, 
									scale_up_button = self._button[31], 
									scale_down_button = self._button[30],
									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],))

		self._instrument.drumpad_shift_layer = AddLayerMode(self._instrument, Layer(priority = 5, 
									scale_up_button = self._button[31],
									scale_down_button = self._button[30],
									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],))

		self._instrument._keypad.sequencer_layer = LayerMode(self._instrument._keypad, Layer(priority = 5, 
																										playhead = self._playhead_element,
		 																								keypad_matrix = self._matrix.submatrix[:,:],))
		self._instrument._keypad.split_layer = LayerMode(self._instrument._keypad, Layer(priority = 5, 
																										keypad_matrix = self._matrix.submatrix[:,:],))
		self._instrument._keypad.sequencer_shift_layer = LayerMode(self._instrument._keypad, Layer(priority = 5, 
																										keypad_matrix = self._matrix.submatrix[:,:], 
																										loop_selector_matrix = self._key_matrix.submatrix[4:8, 0], 
																										quantization_buttons = self._key_matrix.submatrix[:7, 1], 
																										follow_button = self._button[23]))
		self._instrument._keypad.sequencer_session_layer = LayerMode(self._instrument._keypad, Layer(priority = 5, 
																										playhead = self._playhead_element,))
		self._instrument._keypad.split_session_layer = LayerMode(self._instrument._keypad, Layer(priority = 5, 
																										split_matrix = self._key_matrix.submatrix[:16,:1]))
		self._instrument._keypad.sequencer_session_shift_layer = LayerMode(self._instrument._keypad, Layer(priority = 5,
																										loop_selector_matrix = self._key_matrix.submatrix[4:8, :1], 
																										quantization_buttons = self._key_matrix.submatrix[:7, 1:], 
																										follow_button = self._button[23]))

		self._instrument._drumpad.sequencer_layer = LayerMode(self._instrument._drumpad, Layer(priority = 5, 
																										playhead = self._playhead_element, 
																										drumpad_matrix = self._matrix.submatrix[:,:],))
		self._instrument._drumpad.split_layer = LayerMode(self._instrument._drumpad, Layer(priority = 5, 
																										drumpad_matrix = self._matrix.submatrix[:,:], 
																										split_matrix = self._key_matrix.submatrix[:16,:1]))
		self._instrument._drumpad.sequencer_shift_layer = LayerMode(self._instrument._drumpad, Layer(priority = 5, 
																										drumpad_matrix = self._matrix.submatrix[:,:], 
																										loop_selector_matrix = self._key_matrix.submatrix[4:8, :1], 
																										quantization_buttons = self._key_matrix.submatrix[:7, 1:], 
																										follow_button = self._button[23]))
		self._instrument._drumpad.sequencer_session_layer = LayerMode(self._instrument._drumpad, Layer(priority = 5, 
																										playhead = self._playhead_element,))
		self._instrument._drumpad.split_session_layer = LayerMode(self._instrument._drumpad, Layer(priority = 5, 
																										split_matrix = self._key_matrix.submatrix[:16,:1]))
		self._instrument._drumpad.sequencer_session_shift_layer = LayerMode(self._instrument._drumpad, Layer(priority = 5, 
																										loop_selector_matrix = self._key_matrix.submatrix[4:8, :1], 
																										quantization_buttons = self._key_matrix.submatrix[:7, 1:], 
																										follow_button = self._button[23]))

		#self._instrument.set_session_mode_button(self._button[30])
	

	def _setup_modes(self):

		common = CompoundMode(self._mixer,
									self._session_ring)
		main_buttons=CompoundMode(self._G_mixer.main_buttons_layer,
									self._session_navigation,
									self._session_navigation.nav_layer,
									self._transport,
									self._transport.overdub_layer,
									self._recorder,
									self._recorder.main_layer, 
									self._device)
		shifted_main_buttons=CompoundMode(self._G_mixer.shifted_buttons_layer,
									self._recorder, 
									self._recorder.shift_layer,
									self._session,
									self._session.scene_launch_layer,
									self._session.stop_clips_layer,
									self._transport,
									self._device)
		main_faders=CompoundMode(self._G_mixer.main_faders_layer, 
									self._G_mixer.master_fader_layer)
		main_dials=CompoundMode(self._view_control,
									self._view_control.main_layer,
									self._device_navigator,
									self._device_navigator.select_dial_layer, 
									self.encoder_navigation_on)
		shifted_dials=CompoundMode(self._session_navigation,
									self._session_navigation.nav_dial_layer,
									self._device_navigator,
									self._device_navigator.select_dial_layer,
									self.encoder_navigation_on)

		self._modalt_mode = ModesComponent(name = 'ModAltMode')
		self._modalt_mode.add_mode('disabled', None)
		self._modalt_mode.add_mode('enabled', [tuple([self._enable_mod_alt, self._disable_mod_alt])], behaviour = CancellableBehaviourWithRelease(), cycle_mode_button_color = 'Mod.AltOn')
		self._modalt_mode.selected_mode = 'disabled'
		self._modalt_mode.set_enabled(False)
		self._modalt_mode.layer = Layer(priority = 4, enabled_button = self._encoder_button[1])

		self._modswitcher = ModesComponent(name = 'ModSwitcher')
		self._modswitcher.add_mode('mod', [self.modhandler, self._modalt_mode, main_faders, self._G_mixer.main_knobs_layer, self._device, self._device_navigator.main_layer,	main_dials, DelayMode(self.modhandler.update, delay = .5, parent_task_group = self._task_group)])
		self._modswitcher.add_mode('instrument', [self._instrument.shift_button_layer, main_buttons, main_faders, self._G_mixer.main_knobs_layer, self._device, self._device_navigator.main_layer]) #self._instrument.shift_button_layer, self._optional_translations])
		self._modswitcher.selected_mode = 'instrument'
		self._modswitcher.set_enabled(False)

		self._instrument._main_modes = ModesComponent(name = 'InstrumentModes')
		self._instrument._main_modes.add_mode('disabled', [main_buttons, main_dials, self._device.main_layer, self._session, self._session, self._session.clip_launch_layer])
		self._instrument._main_modes.add_mode('drumpad', [self._instrument._drumpad.sequencer_layer, 
																					main_buttons, 
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_split', [self._instrument._drumpad.split_layer,
																					self._instrument._selected_session,
																					main_buttons, 
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer', [self._instrument._drumpad.sequencer_layer, 
																					main_buttons, 
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_shifted', [self._instrument._drumpad.sequencer_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons, 
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_split_shifted', [self._instrument._drumpad.split_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons, 
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer_shifted', [self._instrument._drumpad.sequencer_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons, 
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad', [self._instrument._keypad.sequencer_layer, 
																					main_buttons, 
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_split', [self._instrument._keypad.split_layer,
																					self._instrument._selected_session,
																					main_buttons, 
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer', [self._instrument._keypad.sequencer_layer, 
																					main_buttons, 
																					self._device.main_layer,
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_shifted', [self._instrument._keypad.sequencer_shift_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_split_shifted', [self._instrument._keypad.split_layer, 
																					self._instrument.keypad_shift_layer,
																					shifted_main_buttons, 
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer_shifted', [self._instrument._keypad.sequencer_shift_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons, 
																					self._device.main_layer,
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_session', [self._instrument._drumpad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_split_session', [self._instrument._drumpad.split_session_layer,
																					self._instrument._selected_session,
																					main_buttons,
																					self._device.main_layer,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer_session', [self._instrument._drumpad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session,  
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('drumpad_shifted_session', [self._instrument._drumpad.sequencer_session_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					main_buttons, 
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_split_shifted_session', [self._instrument._drumpad.split_session_layer,
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('drumpad_sequencer_shifted_session', [self._instrument._drumpad.sequencer_session_shift_layer, 
																					self._instrument.drumpad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_session', [self._instrument._keypad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session, 
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_split_session', [self._instrument._keypad.split_session_layer,
																					self._instrument._selected_session,
																					main_buttons,
																					self._device.main_layer,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer_session', [self._instrument._keypad.sequencer_session_layer, 
																					main_buttons,
																					self._device.main_layer,
																					self._session, 
																					DelayMode(self._session.clip_launch_layer, delay = .1), 
																					main_dials])
		self._instrument._main_modes.add_mode('keypad_shifted_session', [self._instrument._keypad.sequencer_session_shift_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_split_shifted_session', [self._instrument._keypad.split_session_layer, 
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		self._instrument._main_modes.add_mode('keypad_sequencer_shifted_session', [self._instrument._keypad.sequencer_session_shift_layer,
																					self._instrument.keypad_shift_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])

		self._instrument._main_modes.add_mode('audioloop', [self._instrument.audioloop_layer, 
																					main_buttons, 
																					self._device.main_layer,
																					main_dials,
																					self._session,
																					DelayMode(self._session.clip_launch_layer, delay = .1)])
		self._instrument._main_modes.add_mode('audioloop_shifted', [self._instrument.audioloop_layer, 
																					shifted_main_buttons,
																					self._device.main_layer,
																					self._session_zoom, 
																					shifted_dials])
		#self._instrument._main_modes.add_mode('audioloop_shifted_session', [self._instrument.audioloop_layer, self._session, shifted_main_buttons, main_dials, shifted_dials])
		self._instrument.register_component(self._instrument._main_modes)
		self._instrument._main_modes.selected_mode = 'disabled'
		self._instrument.set_enabled(True)

		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('disabled', [self._background])
		self._main_modes.add_mode('MixMode', [common, 
													self._instrument, 
													self._instrument.shift_button_layer,
													self._G_mixer,
													main_faders, 
													self._G_mixer.main_knobs_layer,
													self._device,
													self._device.main_layer,
													self._device_navigator,
													self._device_navigator.main_layer,
													self._device_navigator.select_dial_layer])
		self._main_modes.add_mode('ModSwitcher', [common,
													main_faders, 
													main_dials, 
													self._G_mixer.main_knobs_layer,
													self._view_control,
													self._view_control.main_layer, 
													self._device_navigator,
													self._device_navigator.select_dial_layer, 
													self.encoder_navigation_on, 
													self._modswitcher, 
													DelayMode(self._update_modswitcher, delay = .1)], 
													behaviour = ColoredCancellableBehaviourWithRelease(color = 'ModeButtons.ModSwitcher', off_color = 'ModeButtons.ModSwitcherDisabled'))
		self._main_modes.add_mode('Translations', [common, 
													main_faders, 
													main_dials,
													self._G_mixer.main_knobs_layer, 
													self._translations, 
													DelayMode(self._translations.selector_layer, delay = .1)], 
													behaviour = DefaultedBehaviour(default_mode = 'MixMode', color = 'ModeButtons.Translations', off_color = 'ModeButtons.TranslationsDisabled'))
		self._main_modes.add_mode('DeviceSelector', [common,
													self._device_selector,
													DelayMode(self._device_selector.select_layer, delay = .1),
													DelayMode(self.modhandler.lock_layer, delay = .1),
													DelayMode(self._device_selector.assign_layer, delay = .5), 
													main_buttons, 
													main_dials, 
													main_faders, 
													self._G_mixer.main_knobs_layer, 
													self._device.main_layer,
													self._device_navigator,
													self._device_navigator.main_layer,
													self._device_navigator.select_dial_layer], 
													behaviour = ColoredCancellableBehaviourWithRelease(color = 'ModeButtons.DeviceSelector', off_color = 'ModeButtons.DeviceSelectorDisabled'))
		self._main_modes.layer = Layer(priority = 4, ModSwitcher_button = self._encoder_button[2], DeviceSelector_button = self._encoder_button[0], Translations_button = self._encoder_button[3]) #, 
		self._main_modes.selected_mode = 'disabled'
		self._main_modes.set_enabled(True)

		self._test.subject = self._instrument._main_modes
	



#a
Example #22
0
class Aum256(ControlSurface):

    _rgb = 0
    _color_type = 'Push'
    _timer = 0
    _touched = 0
    flash_status = False
    _model_name = 'Aum256'
    _host_name = 'Aum256'
    _version_check = 'b996'
    monomodular = None
    device_provider_class = ModDeviceProvider

    def __init__(self, *a, **k):
        super(Aum256, self).__init__(*a, **k)
        self.log_message = logger.info
        self._skin = Skin(Aum256Colors)
        with self.component_guard():
            self._setup_monobridge()
            self._setup_controls()
            #self._setup_device()
            self._setup_mod()
            #self._setup_modes()
            self._setup_modswitcher()
        self._on_device_changed.subject = self._device_provider
        self.schedule_message(1, self._open_log)

    def _open_log(self):
        #self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._model_name) + " " + str(self._version_check) + " log opened =>>>>>>>>>>>>>>>>>>>")
        self.show_message(str(self._model_name) + ' Control Surface Loaded')

    def _close_log(self):
        #self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._model_name) + " " + str(self._version_check) + " log closed =>>>>>>>>>>>>>>>>>>>")
        pass

    @listenable_property
    def pipe(self):
        return None

    def _send(self, **a):
        notify_pipe(a)

    def _setup_controls(self):
        is_momentary = True
        optimized = True
        resource = PrioritizedResource
        #self._pads_raw = [ ButtonElement(True, MIDI_NOTE_TYPE, 0, identifier, name=u'Pad_{}'.format(identifier), skin=skin) for identifier in xrange(100) ]
        self._pad = [
            SpecialMonoButtonElement(is_momentary=is_momentary,
                                     msg_type=MIDI_NOTE_TYPE,
                                     channel=int(math.floor(index / 128)),
                                     identifier=index % 128,
                                     name='Pad_' + str(index),
                                     script=self,
                                     monobridge=self._monobridge,
                                     skin=self._skin,
                                     color_map=COLOR_MAP,
                                     optimized_send_midi=optimized,
                                     resource_type=resource)
            for index in range(256)
        ]
        for button in self._pad:
            button.set_color_map(tuple(range(128)))
        self._matrix = ButtonMatrixElement(
            name='Matrix',
            rows=[
                self._pad[(index * 16):(index * 16) + 16]
                for index in range(16)
            ])
        self._key = [
            SpecialMonoButtonElement(is_momentary=is_momentary,
                                     msg_type=MIDI_NOTE_TYPE,
                                     channel=2,
                                     identifier=index,
                                     name='Key_' + str(index),
                                     script=self,
                                     monobridge=self._monobridge,
                                     skin=self._skin,
                                     color_map=COLOR_MAP,
                                     optimized_send_midi=optimized,
                                     resource_type=resource)
            for index in range(8)
        ]
        for button in self._pad:
            button.set_color_map(tuple(range(128)))
        self._key_matrix = ButtonMatrixElement(name='KeyMatrix',
                                               rows=[self._key])

        self._shift = SpecialMonoButtonElement(is_momentary=is_momentary,
                                               msg_type=MIDI_NOTE_TYPE,
                                               channel=2,
                                               identifier=8,
                                               name='Shift',
                                               script=self,
                                               monobridge=self._monobridge,
                                               skin=self._skin,
                                               color_map=COLOR_MAP,
                                               optimized_send_midi=optimized,
                                               resource_type=resource)
        self._shift.set_color_map(tuple(range(128)))
        self._alt = SpecialMonoButtonElement(is_momentary=is_momentary,
                                             msg_type=MIDI_NOTE_TYPE,
                                             channel=2,
                                             identifier=9,
                                             name='Alt',
                                             script=self,
                                             monobridge=self._monobridge,
                                             skin=self._skin,
                                             color_map=COLOR_MAP,
                                             optimized_send_midi=optimized,
                                             resource_type=resource)
        self._alt.set_color_map(tuple(range(128)))
        self._lock = SpecialMonoButtonElement(is_momentary=is_momentary,
                                              msg_type=MIDI_NOTE_TYPE,
                                              channel=2,
                                              identifier=10,
                                              name='Lock',
                                              script=self,
                                              monobridge=self._monobridge,
                                              skin=self._skin,
                                              color_map=COLOR_MAP,
                                              optimized_send_midi=optimized,
                                              resource_type=resource)
        self._lock.set_color_map(tuple(range(128)))

    #def _setup_device(self):
    #	self._device_selection_follows_track_selection = True
    #	self._device = DeviceComponent(name = 'Device_Component', device_bank_registry = DeviceBankRegistry(), device_provider = self._device_provider)
    #	self._device.set_enabled(True)

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

    def _setup_mod(self):
        def get_monomodular(host):
            if isinstance(__builtins__, dict):
                if not 'monomodular' in list(
                        __builtins__.keys()) or not isinstance(
                            __builtins__['monomodular'], ModRouter):
                    __builtins__['monomodular'] = ModRouter(
                        song=self.song,
                        register_component=self._register_component)
            else:
                if not hasattr(__builtins__, 'monomodular') or not isinstance(
                        __builtins__['monomodular'], ModRouter):
                    setattr(
                        __builtins__, 'monomodular',
                        ModRouter(song=self.song,
                                  register_component=self._register_component))
            monomodular = __builtins__['monomodular']
            if not monomodular.has_host():
                monomodular.set_host(host)
            return monomodular

        self.monomodular = get_monomodular(self)
        self.monomodular.name = 'monomodular_switcher'
        # with inject(register_component = const(self._register_component), song = const(self.song)).everywhere():
        self.modhandler = Aum256ModHandler(
            self
        )  ## song = self.song, register_component = self._register_component)
        self.modhandler.name = 'ModHandler'
        self.modhandler.layer = Layer(priority=6,
                                      grid=self._matrix,
                                      Shift_button=self._shift,
                                      Alt_button=self._alt,
                                      key_buttons=self._key_matrix)
        self.modhandler.alt_shift_layer = AddLayerMode(self.modhandler,
                                                       Layer())
        self.modhandler.legacy_shift_layer = AddLayerMode(
            self.modhandler,
            Layer(
                priority=7,
                device_selector_matrix=self._matrix.submatrix[:, :1],
                channel_buttons=self._matrix.submatrix[:, 1:2],
            ))
        #nav_matrix = self._matrix.submatrix[4:8, 2:6],
        #))
        self.modhandler.shift_layer = AddLayerMode(
            self.modhandler,
            Layer(
                priority=7,
                device_selector_matrix=self._matrix.submatrix[:, :1],
            ))
        #lock_button = self.elements.master_select_button,
        #))
        self.modhandler.alt_layer = AddLayerMode(self.modhandler,
                                                 Layer(priority=7, ))
        #key_buttons = self.elements.select_buttons))
        #key_buttons = self.elements.track_state_buttons))
        self._device_provider.restart_mod()
        self._modHandle = ModControl(modscript=self,
                                     monomodular=self.monomodular,
                                     name='ModHandle')

    def _setup_modswitcher(self):
        self._modswitcher = ModesComponent(name='ModSwitcher')
        self._modswitcher.add_mode('mod', [self.modhandler])
        self._modswitcher.selected_mode = 'mod'
        self._modswitcher.set_enabled(True)

    def flash(self):
        if (self.flash_status > 0):
            for control in self.controls:
                if isinstance(control, MonoButtonElement):
                    control.flash(self._timer)

    def update_display(self):
        super(ControlSurface, self).update_display()
        self._timer = (self._timer + 1) % 256
        self.flash()

    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)

    @listens('device')
    def _on_device_changed(self):
        #self.schedule_message(1, self._update_modswitcher)
        debug('Aum256 on_device_changed')
        #self._update_modswitcher()

    def _on_selected_track_changed(self):
        super(Aum256, self)._on_selected_track_changed()
        if not len(self.song.view.selected_track.devices):
            self._update_modswitcher()
        #self.schedule_message(1, self._update_modswitcher)

    def disconnect(self):
        for script in self._connected_scripts:
            if hasattr(script, '_disconnect_mod'):
                script._disconnect_mod()
        super(Aum256, self).disconnect()
        self._close_log()

    def restart_monomodular(self):
        #self.log_message('restart monomodular')
        self.modhandler.disconnect()
        with self.component_guard():
            self._setup_mod()

    def _do_send_midi(self, midi_event_bytes):
        super(Aum256, self)._do_send_midi(midi_event_bytes)
        bytes = list(midi_event_bytes)
        self.notify_pipe('midi', *bytes)

    def receive_note(self, num, val, chan=0):
        # debug('receive_note', num, val)
        self.receive_midi(tuple([144 + chan, num, val]))

    def receive_cc(self, num, val, chan=0):
        # debug('receive_cc', num, val)
        self.receive_midi(tuple([176 + chan, num, val]))

    def process_midi_bytes(self, midi_bytes, midi_processor):
        """
		Finds the right recipient for the MIDI message and translates it into the
		expected format. The result is forwarded to the midi_processor.
		"""
        if midi.is_sysex(midi_bytes):
            result = self.get_registry_entry_for_sysex_midi_message(midi_bytes)
            if result is not None:
                identifier, recipient = result
                midi_processor(recipient, midi_bytes[len(identifier):-1])
            #elif self.received_midi_listener_count() == 0:
            #	logger.warning(u'Got unknown sysex message: ' + midi.pretty_print_bytes(midi_bytes))
        else:
            recipient = self.get_recipient_for_nonsysex_midi_message(
                midi_bytes)
            if recipient is not None:
                midi_processor(recipient, midi.extract_value(midi_bytes))
            #elif self.received_midi_listener_count() == 0:
            #	logger.warning(u'Got unknown message: ' + midi.pretty_print_bytes(midi_bytes))

    def connect_script_instances(self, instanciated_scripts):
        debug('connect_script_instances', instanciated_scripts)
        self._connected_scripts = []
        for script in instanciated_scripts:
            # debug(script)
            if isinstance(script, Launchpad_MK2):
                self._connected_scripts.append(script)
                self._on_lp2_mode_changed.subject = script._modes
                if not hasattr(script, '_modified') or (hasattr(
                        script, '_modified') and not script._modified):
                    script.setup_mod = _Launchpad_MK2_setup_mod
                    script.schedule_message(1, script.setup_mod,
                                            [script, self])
            elif isinstance(script, Launchpad_Pro):
                self._connected_scripts.append(script)
                self._on_lppro_mode_changed.subject = script._note_modes
                if not hasattr(script, '_modified') or (hasattr(
                        script, '_modified') and not script._modified):
                    script.setup_mod = _Launchpad_Pro_setup_mod
                    script.schedule_message(1, script.setup_mod,
                                            [script, self])
            elif isinstance(script, Launchpad):
                self._connected_scripts.append(script)
                # self._on_lppro_mode_changed.subject = script._note_modes
                if not hasattr(script, '_modified') or (hasattr(
                        script, '_modified') and not script._modified):
                    script.setup_mod = _Launchpad_setup_mod
                    script.schedule_message(1, script.setup_mod,
                                            [script, self])
        debug('connected_scripts:', self._connected_scripts)

    @listens('selected_mode')
    def _on_lp2_mode_changed(self, mode):
        debug('_on_lp2_mode_changed', mode)

    @listens('selected_mode')
    def _on_lppro_mode_changed(self, mode):
        debug('_on_lppro_mode_changed', mode)
Example #23
0
class Cntrlr(Base_Cntrlr):


	def __init__(self, *a, **k):
		super(Cntrlr, self).__init__(*a, **k)
		self._skin = Skin(CntrlrColors)
		for button in self._grid:
			button._skin = self._skin
		self._main_modes.selected_mode = 'Translations'
		self.schedule_message(3, self.initialize_translations)
	

	def initialize_santos_mode(self):
		self._main_modes.selected_mode = 'SantosMode'
		self._device_toggle.scan_all()
		self._session_ring.set_offsets(1, 0)
	

	def initialize_translations(self):
		self._main_modes.selected_mode = "Translations"
		self.schedule_message(3, self.initialize_santos_mode)
	

	def _open_log(self):
		self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) + " for Santos Garcia " + str(self._version_check) + " log opened =>>>>>>>>>>>>>>>>>>>") 
		self.show_message(str(self._host_name) + ' Control Surface Loaded')
	

	def _setup_device_toggle(self):
		self._device_toggle = ToggleDeviceEnabledComponent(self, "@dd")
		self._device_toggle.layer = Layer(priority = 9,  matrix = self._key_matrix.submatrix[4:12, 1:])
		self._device_toggle.set_enabled(False)
	

	def _update_session_position(self):
		self._session_ring.set_offsets(1, 0)
	

	def _setup_mixer_control(self):
		self._mixer = MonoMixerComponent(name = 'Mixer', num_returns = 4,tracks_provider = SessionRingComponent(num_tracks = 4, num_scenes = 4), track_assigner = simple_track_assigner, invert_mute_feedback = True, auto_name = True, enable_skinning = True)

		if FREE_ENCODER_IS_CROSSFADER:
			self._mixer.layer = Layer(priority = 4, crossfader_control = self._encoder[1])
		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:, :],))
		self._mixer.main_buttons_layer = AddLayerMode(self._mixer, Layer(priority = 4, 
											mute_buttons = self._key_matrix.submatrix[8:12, 1:],
											stop_clip_buttons = self._key_matrix.submatrix[4:8, 1:],
											arming_track_select_buttons = self._key_matrix.submatrix[:4, 1:],))
		self._mixer.solo_buttons_layer = AddLayerMode(self._mixer, Layer(priority = 4,
											solo_buttons = self._key_matrix.submatrix[8:12, 1:],))
		self._mixer.shifted_buttons_layer = AddLayerMode(self._mixer, Layer(priority = 4,
											track_select_buttons = self._key_matrix.submatrix[:4, 1:],
											stop_clip_buttons = self._key_matrix.submatrix[4:8, 1:],
											solo_buttons = self._key_matrix.submatrix[8:12, 1:],))
		self._mixer.stop_layer = AddLayerMode(self._mixer, Layer(priority = 4,
											stop_clip_buttons = self._key_matrix.submatrix[8:12, 1:],))
		if EQS_INSTEAD_OF_MACROS:
			self._mixer.main_knobs_layer = AddLayerMode(self._mixer, Layer(priority = 4,
												send_controls = self._knob_left_matrix,
												eq_gain_controls = self._knob_right_matrix))
		else:
			self._mixer.main_knobs_layer = AddLayerMode(self._mixer, Layer(priority = 4,
												send_controls = self._knob_left_matrix,
												parameter_controls = self._knob_right_matrix))
		#self._mixer.main_knobs_layer = AddLayerMode(self._mixer, Layer(priority = 4))
		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.set_enabled(False)
	

	def _setup_session_control(self):
		self._session_ring = SessionRingComponent(num_tracks = 3, num_scenes = 4)
		self._session_ring.set_enabled(False)


		self._session_navigation = CntrlrSessionNavigationComponent(name = 'SessionNavigation', session_ring = self._session_ring)

		self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'

		self._session_navigation.bank_dial_layer = AddLayerMode(self._session_navigation, Layer(priority = 5, 
									track_bank_dial = self._encoder[3], 
									scene_bank_dial = self._encoder[2],))
		self._session_navigation.nav_dial_layer = AddLayerMode(self._session_navigation, Layer(priority = 5,
									scene_nav_dial = self._encoder[2],
									track_nav_dial = self._encoder[3],))
		self._session_navigation.select_dial_layer = AddLayerMode(self._session_navigation, Layer(priority = 5))
		"""self._session_navigation.nav_layer = AddLayerMode(self._session_navigation, Layer(priority = 4,
									page_down_button = self._button[14],
									page_up_button = self._button[15],
									page_left_button = self._button[12],
									page_right_button = self._button[13]))"""
		self._session_navigation.nav_layer = AddLayerMode(self._session_navigation, Layer(priority = 4))

		self._session_navigation.set_enabled(False)

		self._session = SpecialCntrlrSessionComponent(session_ring = self._session_ring, auto_name = True)
		hasattr(self._session, '_enable_skinning') and self._session._enable_skinning()
		self._session.clip_launch_layer = LayerMode(self._session, Layer(priority = 4,
									clip_launch_buttons = self._matrix.submatrix[:,:]))
		self._session.scene_launch_layer = AddLayerMode(self._session._selected_scene, Layer(priority = 4, 
									launch_button = self._button[28],))
		self._session.set_enabled(False)

		self._session_zoom = SessionOverviewComponent(name = 'SessionZoom', session_ring = self._session_ring, enable_skinning = True)
		self._session_zoom.layer = Layer(priority = 4, button_matrix = self._matrix.submatrix[:,:])

		self._session.clip_launch_layer = LayerMode(self._session, Layer(priority = 4,
									clip_launch_buttons = self._matrix.submatrix[:3,:],
									scene_launch_buttons = self._matrix.submatrix[3:,:]))
		self._session_ring.set_offsets(1, 0)

		self._session_zoom.set_enabled(False)
	

	def _setup_translations2(self):
		self._translated_controls2 = self._knobs  #+ self._button[:20] + self._button[28:]

		self._translations2 = TranslationComponent(self._translated_controls2, user_channel_offset = 9, channel = 9)
		self._translations2.name = 'TranslationComponent'
		self._translations2.layer = Layer(priority = 10,)
		self._translations2.set_enabled(False)
	

	def _setup_modes(self):

		self._setup_device_toggle()
		self._setup_translations2()

		self._mixer.santos_buttons_layer = AddLayerMode(self._mixer, Layer(priority = 4,
											arming_track_select_buttons = self._key_matrix.submatrix[:4, 1:],))

		super(Cntrlr, self)._setup_modes()

		common = CompoundMode(self._mixer,
									self._session_ring)
		main_buttons=CompoundMode(self._mixer.main_buttons_layer, 
									self._transport,
									self._recorder,
									self._recorder.main_layer, 
									self._device,
									self._device.button_layer)
		shifted_main_buttons=CompoundMode(self._mixer.solo_buttons_layer, 
									self._recorder, 
									self._recorder.shift_layer,
									self._session,
									self._session.scene_launch_layer,
									self._device,
									self._device.button_layer)
		main_faders=CompoundMode(self._mixer.main_faders_layer, 
									self._mixer.master_fader_layer)
		main_dials=CompoundMode(self._view_control,
									self._view_control.main_layer,
									self._device,
									self._device.dial_layer,
									self._device_navigator.select_dial_layer, 
									self.encoder_navigation_on)
		shifted_dials=CompoundMode(self._session_navigation,
									self._session_navigation.nav_dial_layer,
									self._device,
									self._device.dial_layer,
									self._device_navigator.select_dial_layer,
									self.encoder_navigation_on)



		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('disabled', [self._background])
		self._main_modes.add_mode('MixMode', [common, 
													self._instrument, 
													self._instrument.shift_button_layer,
													self._mixer,
													main_faders, 
													self._mixer.main_knobs_layer,
													self._device,
													self._device_navigator,
													self._device_navigator.main_layer,],
													behaviour = DefaultedBehaviour(default_mode = 'SantosMode',color = 'ModeButtons.DeviceSelector', off_color = 'ModeButtons.DeviceSelectorDisabled'))
		self._main_modes.add_mode('ModSwitcher', [common,
													main_faders, 
													main_dials, 
													self._mixer.main_knobs_layer, 
													self._session_navigation.select_dial_layer, 
													self._view_control,
													self._view_control.main_layer, 
													self._device_navigator.select_dial_layer, 
													self.encoder_navigation_on, self._modswitcher, 
													DelayMode(self._update_modswitcher, delay = .1)], 
													behaviour = ColoredCancellableBehaviourWithRelease(color = 'ModeButtons.ModSwitcher', off_color = 'ModeButtons.ModSwitcherDisabled'))
		self._main_modes.add_mode('Translations', [common, 
													main_faders, 
													main_dials,
													self._mixer.main_knobs_layer, 
													self._translations, 
													DelayMode(self._translations.selector_layer, delay = .1)], 
													behaviour = DefaultedBehaviour(default_mode = 'SantosMode', color = 'ModeButtons.Translations', off_color = 'ModeButtons.TranslationsDisabled'))
		self._main_modes.add_mode('DeviceSelector', [common,
													self._device_selector,
													DelayMode(self._device_selector.select_layer, delay = .1),
													DelayMode(self.modhandler.lock_layer, delay = .1),
													DelayMode(self._device_selector.assign_layer, delay = .5), 
													main_buttons, 
													main_dials, 
													main_faders, 
													self._mixer.main_knobs_layer, 
													self._device,
													self._device_navigator], 
													behaviour = ColoredCancellableBehaviourWithRelease(color = 'ModeButtons.DeviceSelector', off_color = 'ModeButtons.DeviceSelectorDisabled'))
		self._main_modes.add_mode('SantosMode', [self._mixer, 
													self._mixer.main_faders_layer, 
													self._device_toggle, 
													self._translations2, 
													self._instrument, 
													self._instrument.shift_button_layer, 
													self._mixer.santos_buttons_layer, 
													self._device, self._device_navigator, 
													self._session_ring, 
													DelayMode(self._update_session_position, delay = .1)], )

		self._main_modes.layer = Layer(priority = 4, ModSwitcher_button = self._encoder_button[2], MixMode_button = self._encoder_button[0], Translations_button = self._encoder_button[3]) #, 
		self._main_modes.selected_mode = 'disabled'
		self._main_modes.set_enabled(True)	

	



#	a
Example #24
0
class MonoPedal(ControlSurface):
    def __init__(self, *a, **k):
        self.log_message = logger.warning
        super(MonoPedal, self).__init__(*a, **k)
        self._monomod_version = 'b996'
        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(is_momentary=True,
                                  msg_type=MIDI_CC_TYPE,
                                  channel=0,
                                  identifier=PEDAL_DEFS[index],
                                  name='Pedal_' + str(index),
                                  script=self))
            self._pedal[index]._report = False
        self._pedal[7] = LoopPedalExpressionElement(
            script=self,
            msg_type=MIDI_CC_TYPE,
            channel=0,
            identifier=1,
            map_mode=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,
                                        is_momentary=True,
                                        msg_type=MIDI_NOTE_TYPE,
                                        channel=0,
                                        identifier=index + 13,
                                        name='LED_' + str(index),
                                        script=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)
Example #25
0
class MonoFCBE3(ControlSurface):
    def __init__(self, *a, **k):
        self.log_message = logger.warning
        super(MonoFCBE3, self).__init__(*a, **k)
        self._monomod_version = 'b996'
        self._codec_version = 'b996'
        self._cntrlr_version = 'b996'
        self._cntrlr = None
        self._host_name = 'MonoFCBE3'
        self._color_type = 'Monochrome'
        self.hosts = []
        self._timer = 0
        self.flash_status = 1
        self._touched = 0
        self._last_main_mode = 'looper'
        self._skin = Skin(MONOFCBColors)
        with self.component_guard():
            self._setup_monobridge()
            self._setup_controls()
            self._setup_looper()
            #self._setup_undo()
            self._setup_delete_actions()
            #self._setup_autoarm()
            self._setup_viewcontrol()
            self._setup_session_recording_component()
            self._setup_mixer()
            self._setup_modes()
        #self._on_device_changed.subject = self._device_provider
        self.schedule_message(1, self._open_log)
        self._on_device_changed.subject = self._device_provider
        self._on_selected_track_changed.subject = self.song.view
        #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(14)]
        for index in range(5):
            self._pedal[index] = DoublePressElement(
                MonoButtonElement(is_momentary=True,
                                  msg_type=MIDI_NOTE_TYPE,
                                  channel=0,
                                  identifier=PEDAL_DEFS[index],
                                  name='Pedal_' + str(index),
                                  script=self,
                                  skin=self._skin))
            self._pedal[index]._report = False
        for index in range(7):
            self._pedal[index + 5] = MonoButtonElement(
                is_momentary=True,
                msg_type=MIDI_NOTE_TYPE,
                channel=0,
                identifier=PEDAL_DEFS[index + 5],
                name='Pedal_' + str(index + 5),
                script=self,
                skin=self._skin)
            self._pedal[index + 5]._report = False
        self._pedal[12] = LoopPedalExpressionElement(
            script=self,
            msg_type=MIDI_CC_TYPE,
            channel=0,
            identifier=102,
            map_mode=Live.MidiMap.MapMode.absolute)
        self._pedal[12].name = 'Pedal_' + str(12)
        self._pedal[12]._report = False
        self._pedal[13] = LoopPedalExpressionElement(
            script=self,
            msg_type=MIDI_CC_TYPE,
            channel=0,
            identifier=103,
            map_mode=Live.MidiMap.MapMode.absolute)
        self._pedal[13].name = 'Pedal_' + str(13)
        self._pedal[13]._report = False
        self._leds = self._pedal[5:9]
        self._select_buttons = ButtonMatrixElement()
        self._select_buttons.name = 'SelectMatrix'
        self._select_buttons.add_row(
            [self._pedal[5], self._pedal[6], self._pedal[7], self._pedal[8]])
        #self._doublepress_select_buttons = ButtonMatrixElement()
        #self._doublepress_select_buttons.name = 'DoublepressSelectMatrix'
        #self._doublepress_select_buttons.add_row([self._pedal[9].double_press, self._pedal[8].double_press, self._pedal[7].double_press, self._pedal[6].double_press])

        self._overdub_button = self._pedal[0]
        self._record_button = self._pedal[1]
        self._mute_button = self._pedal[2]
        self._reverse_button = self._pedal[3]

    def _setup_mixer(self):
        self._session_ring = SessionRingComponent(name='Session_Ring',
                                                  num_tracks=0,
                                                  num_scenes=0)
        self._mixer = MonoMixerComponent(name='Mixer',
                                         tracks_provider=self._session_ring,
                                         track_assigner=simple_track_assigner,
                                         invert_mute_feedback=True,
                                         auto_name=True,
                                         enable_skinning=True)
        self._mixer._selected_strip.layer = Layer(
            priority=4,
            volume_control=self._pedal[13],
            arm_button=self._pedal[7])

    def _setup_looper(self):
        self._looper = MonolooperComponent(self._leds, self)
        self._looper.layer = Layer(
            record_button=self._pedal[0],
            overdub_button=self._pedal[1],
            mute_button=self._pedal[2],
            reverse_button=self._pedal[3],
            trans1_button=self._pedal[5],
            trans2_button=self._pedal[6],
            expression_pedal=self._pedal[12],
        )

    def _setup_undo(self):
        self._undo = UndoRedoComponent(name='Undo', is_root=True)
        self._undo.layer = Layer(undo_button=self._pedal[4])
        self._undo.set_enabled(False)

    def _setup_delete_actions(self):
        #self._delete_component = DeleteComponent(name='Deleter', is_root=True)
        #self._delete_component.layer = Layer(delete_button='delete_button')
        #self._delete_default_component = DeleteAndReturnToDefaultComponent(name='DeleteAndDefault', is_root=True)
        #self._delete_default_component.layer = Layer(delete_button='delete_button')
        self._delete_clip = DeleteSelectedClipComponent(
            name='Selected_Clip_Deleter')
        self._delete_clip.layer = Layer(action_button=self._pedal[4])
        self._delete_clip.set_enabled(False)
        #self._delete_scene = DeleteSelectedSceneComponent(name='Selected_Scene_Deleter', is_root=True)
        #self._delete_scene.layer = Layer(action_button=self._with_shift('delete_button'))

    def _setup_viewcontrol(self):
        self._viewcontrol = ViewControlComponent()
        self._viewcontrol.layer = Layer(priority=4,
                                        prev_track_button=self._pedal[11],
                                        next_track_button=self._pedal[10])
        self._viewcontrol.set_enabled(False)

    def _setup_session_recording_component(self):
        self._clip_creator = ClipCreator()
        self._clip_creator.name = 'ClipCreator'
        self._recorder = FixedLengthSessionRecordingComponent(
            length_values=LENGTH_VALUES,
            clip_creator=self._clip_creator,
            view_controller=self._viewcontrol)

        #self._recorder = FixedLengthSessionRecordingComponent(view_controller = self._viewcontrol)
        self._recorder.layer = Layer(priority=4,
                                     new_button=self._pedal[8],
                                     record_button=self._pedal[9])
        self._recorder.set_enabled(False)

    def _setup_autoarm(self):
        self._auto_arm = AutoArmComponent(name='Auto_Arm')
        self._auto_arm.can_auto_arm_track = self._can_auto_arm_track
        self._auto_arm._update_notification = lambda: None

    def _setup_modes(self):
        self._button_modes = ModesComponent(name='Button_Modes')
        self._button_modes.add_mode('looper', [
            self._looper, self._viewcontrol, self._recorder, self._delete_clip
        ])
        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

    """called on timer"""

    def update_display(self):
        super(MonoFCBE3, 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)

    @listens('selected_track')
    def _on_selected_track_changed(self):
        self.detect_aliased_looper()

    def _can_auto_arm_track(self, track):
        routing = track.current_input_routing
        return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith(
            'Livid Minim Input')

    def detect_aliased_looper(self):
        device = self._device_provider.device
        if device:
            found = -1
            for index in range(16):
                key = str('@loop' + str(index + 1))
                preset = None
                if (match(key, str(device.name)) != None):
                    found = index
                    break
            if found > -1:
                self._looper._select_looper(index)
        else:
            current_track = self.song.view.selected_track
            #debug('current track is:', current_track)
            key = str('@l:')
            looper_number = -1
            if current_track.name.startswith(key) and len(
                    current_track.name) > 4:
                looper_number = int(current_track.name[3]) - 1
            self._looper._select_looper(looper_number)

    @listens('device')
    def _on_device_changed(self):
        debug('on device changed')
        device = self._device_provider.device
        if device:
            found = -1
            for index in range(16):
                key = str('@loop' + str(index + 1))
                preset = None
                if (match(key, str(device.name)) != None):
                    found = index
                    break
            if found > -1:
                self._looper._select_looper(index)
Example #26
0
File: DS1.py Project: aumhaa/m4m8
class DS1(LividControlSurface):

    _sysex_id = 16
    _model_name = 'DS1'

    def __init__(self, c_instance):
        super(DS1, self).__init__(c_instance)
        self._skin = Skin(DS1Colors)
        with self.component_guard():
            self._define_sysex()
            self._setup_controls()
            self._setup_background()
            self._setup_m4l_interface()
            self._setup_session_control()
            self._setup_mixer_control()
            self._setup_transport_control()
            self._setup_device_control()
            self._setup_session_recording_component()
            self._setup_main_modes()

    def _initialize_script(self):
        super(DS1, self)._initialize_script()
        self._main_modes.set_enabled(True)
        self._main_modes.selected_mode = 'Main'

    def _initialize_hardware(self):
        super(DS1, self)._initialize_hardware()
        self.local_control_off.enter_mode()
        self.encoder_absolute_mode.enter_mode()
        self.encoder_speed_sysex.enter_mode()

    def _define_sysex(self):
        self.encoder_speed_sysex = SendLividSysexMode(
            livid_settings=self._livid_settings,
            call='set_encoder_mapping',
            message=ENCODER_SPEED)
        self.encoder_absolute_mode = SendLividSysexMode(
            livid_settings=self._livid_settings,
            call='set_encoder_encosion_mode',
            message=[2])
        self.local_control_off = SendLividSysexMode(
            livid_settings=self._livid_settings,
            call='set_local_control',
            message=[0])

    def _setup_controls(self):
        is_momentary = True
        optimized = True
        resource = PrioritizedResource
        self._fader = [
            MonoEncoderElement(mapping_feedback_delay=-1,
                               msg_type=MIDI_CC_TYPE,
                               channel=CHANNEL,
                               identifier=DS1_FADERS[index],
                               name='Fader_' + str(index),
                               num=index,
                               script=self,
                               optimized_send_midi=optimized,
                               resource_type=resource) for index in range(8)
        ]
        self._dial = [[
            MonoEncoderElement(mapping_feedback_delay=-1,
                               msg_type=MIDI_CC_TYPE,
                               channel=CHANNEL,
                               identifier=DS1_DIALS[x][y],
                               name='Dial_' + str(x) + '_' + str(y),
                               num=x + (y * 5),
                               script=self,
                               optimized_send_midi=optimized,
                               resource_type=resource) for x in range(8)
        ] for y in range(5)]
        self._side_dial = [
            MonoEncoderElement(mapping_feedback_delay=-1,
                               msg_type=MIDI_CC_TYPE,
                               channel=CHANNEL,
                               identifier=DS1_SIDE_DIALS[x],
                               name='Side_Dial_' + str(x),
                               num=x,
                               script=self,
                               optimized_send_midi=optimized,
                               resource_type=resource) for x in range(4)
        ]
        self._encoder = [
            MonoEncoderElement(mapping_feedback_delay=-1,
                               msg_type=MIDI_CC_TYPE,
                               channel=CHANNEL,
                               identifier=DS1_ENCODERS[x],
                               name='Encoder_' + str(x),
                               num=x,
                               script=self,
                               optimized_send_midi=optimized,
                               resource_type=resource) for x in range(4)
        ]
        self._encoder_button = [
            MonoButtonElement(is_momentary=is_momentary,
                              msg_type=MIDI_NOTE_TYPE,
                              channel=CHANNEL,
                              identifier=DS1_ENCODER_BUTTONS[index],
                              name='EncoderButton_' + str(index),
                              script=self,
                              skin=self._skin,
                              optimized_send_midi=optimized,
                              resource_type=resource) for index in range(4)
        ]
        self._master_fader = MonoEncoderElement(msg_type=MIDI_CC_TYPE,
                                                channel=CHANNEL,
                                                identifier=DS1_MASTER,
                                                name='MasterFader',
                                                num=0,
                                                script=self,
                                                optimized_send_midi=optimized,
                                                resource_type=resource)
        self._button = [
            MonoButtonElement(is_momentary=is_momentary,
                              msg_type=MIDI_NOTE_TYPE,
                              channel=CHANNEL,
                              identifier=DS1_BUTTONS[index],
                              name='Button_' + str(index),
                              script=self,
                              skin=self._skin,
                              optimized_send_midi=optimized,
                              resource_type=resource) for index in range(16)
        ]
        self._grid = [[
            MonoButtonElement(is_momentary=is_momentary,
                              msg_type=MIDI_NOTE_TYPE,
                              channel=CHANNEL,
                              identifier=DS1_GRID[x][y],
                              name='Button_' + str(x) + '_' + str(y),
                              script=self,
                              skin=self._skin,
                              optimized_send_midi=optimized,
                              resource_type=resource) for x in range(3)
        ] for y in range(3)]
        self._dummy = [
            MonoEncoderElement(msg_type=MIDI_CC_TYPE,
                               channel=CHANNEL,
                               identifier=120 + x,
                               name='Dummy_Dial_' + str(x),
                               num=x,
                               script=self,
                               optimized_send_midi=optimized,
                               resource_type=resource) for x in range(5)
        ]

        self._fader_matrix = ButtonMatrixElement(name='FaderMatrix',
                                                 rows=[self._fader])
        self._top_buttons = ButtonMatrixElement(name='TopButtonMatrix',
                                                rows=[self._button[:8]])
        self._bottom_buttons = ButtonMatrixElement(name='BottomButtonMatrix',
                                                   rows=[self._button[8:]])
        self._dial_matrix = ButtonMatrixElement(name='DialMatrix',
                                                rows=self._dial)
        self._side_dial_matrix = ButtonMatrixElement(name='SideDialMatrix',
                                                     rows=[self._side_dial])
        self._encoder_matrix = ButtonMatrixElement(name='EncoderMatrix',
                                                   rows=[self._encoder])
        self._encoder_button_matrix = ButtonMatrixElement(
            name='EncoderButtonMatrix', rows=[self._encoder_button])
        self._grid_matrix = ButtonMatrixElement(name='GridMatrix',
                                                rows=self._grid)
        self._selected_parameter_controls = ButtonMatrixElement(
            name='SelectedParameterControls',
            rows=[self._dummy + self._encoder[:1] + self._encoder[2:]])

    def _setup_background(self):
        self._background = BackgroundComponent(name='Background')
        self._background.layer = Layer(
            priority=0,
            fader_matrix=self._fader_matrix,
            top_buttons=self._top_buttons,
            bottom_buttons=self._bottom_buttons,
            dial_matrix=self._dial_matrix,
            side_dial_matrix=self._side_dial_matrix,
            encoder_button_matrix=self._encoder_button_matrix,
            grid_matrix=self._grid_matrix)
        self._background.set_enabled(True)

    def _setup_autoarm(self):
        self._auto_arm = AutoArmComponent(name='Auto_Arm')
        self._auto_arm.can_auto_arm_track = self._can_auto_arm_track

    def _tracks_to_use(self):
        return self.song.visible_tracks + self.song.return_tracks

    def _setup_session_control(self):
        self._session_ring = SessionRingComponent(
            num_tracks=8, num_scenes=1, tracks_to_use=self._tracks_to_use)
        self._session_ring.set_enabled(True)

        self._session_navigation = DS1SessionNavigationComponent(
            name='SessionNavigation', session_ring=self._session_ring)
        self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
        self._session_navigation.layer = Layer(
            priority=4,
            track_select_dial=ComboElement(control=self._encoder[1],
                                           modifier=[self._encoder_button[1]]),
            up_button=self._grid[0][1],
            down_button=self._grid[0][2])
        self._session_navigation.set_enabled(False)

        self._session = DS1SessionComponent(session_ring=self._session_ring,
                                            auto_name=True)
        hasattr(self._session,
                '_enable_skinning') and self._session._enable_skinning()
        self._session.layer = Layer(
            priority=4,
            scene_launch_buttons=self._grid_matrix.submatrix[1:2, 1:2])
        self._session.clips_layer = AddLayerMode(
            self._session,
            Layer(priority=4,
                  clip_launch_buttons=self._top_buttons,
                  stop_track_clip_buttons=self._bottom_buttons))
        self._session.set_enabled(False)

    def _setup_mixer_control(self):

        self._mixer = MonoMixerComponent(
            name='Mixer',
            num_returns=2,
            tracks_provider=self._session_ring,
            track_assigner=SimpleTrackAssigner(),
            invert_mute_feedback=True,
            auto_name=True,
            enable_skinning=True,
            channel_strip_component_type=MonoChannelStripComponent)
        self._mixer.master_strip().set_volume_control(self._master_fader)
        self._mixer.set_prehear_volume_control(self._side_dial[3])
        self._mixer.layer = Layer(volume_controls=self._fader_matrix,
                                  track_select_dial=self._encoder[1])
        self._strip = [self._mixer.channel_strip(index) for index in range(8)]
        if KNOBS_ARE_SENDS:
            for index in range(8):
                self._strip[index].layer = Layer(
                    priority=4,
                    send_controls=self._dial_matrix.submatrix[index:index +
                                                              1, :4],
                    pan_control=self._dial[4][index])
        else:
            for index in range(8):
                self._strip[index].layer = Layer(
                    priority=4,
                    parameter_controls=self._dial_matrix.submatrix[
                        index:index + 1, :])
        self._mixer.selected_strip().layer = Layer(
            priority=4, parameter_controls=self._selected_parameter_controls)
        self._mixer.master_strip().layer = Layer(
            priority=4,
            parameter_controls=self._side_dial_matrix.submatrix[:3, :])
        self._mixer.main_layer = AddLayerMode(
            self._mixer,
            Layer(priority=4,
                  solo_buttons=self._bottom_buttons,
                  mute_buttons=self._top_buttons))
        self._mixer.select_layer = AddLayerMode(
            self._mixer,
            Layer(priority=4,
                  arm_buttons=self._bottom_buttons,
                  track_select_buttons=self._top_buttons))
        self.song.view.selected_track = self._mixer.channel_strip(0)._track
        self._mixer.set_enabled(False)

    def _setup_transport_control(self):
        self._transport = DS1TransportComponent()
        self._transport.name = 'Transport'
        self._transport._record_toggle.view_transform = lambda value: 'Transport.RecordOn' if value else 'Transport.RecordOff'
        self._transport.layer = Layer(priority=4,
                                      stop_button=self._grid[1][0],
                                      play_button=self._grid[0][0],
                                      record_button=self._grid[2][0])
        self._transport.set_enabled(True)

    def _setup_device_control(self):
        self._device = DeviceComponent(
            name='Device_Component',
            device_provider=self._device_provider,
            device_bank_registry=DeviceBankRegistry())

        self._device_navigator = DeviceNavigator(self._device_provider,
                                                 self._mixer, self)
        self._device_navigator.name = 'Device_Navigator'

    def _setup_session_recording_component(self):
        self._clip_creator = ClipCreator()
        self._clip_creator.name = 'ClipCreator'
        self._recorder = SessionRecordingComponent(ViewControlComponent())
        self._recorder.set_enabled(True)
        self._recorder.layer = Layer(
            priority=4,
            automation_button=self._grid[1][2],
            record_button=self._grid[2][1],
        )

    def _setup_m4l_interface(self):
        self._m4l_interface = M4LInterfaceComponent(
            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 _setup_translations(self):
        controls = []
        for control in self.controls:
            controls.append(control)
        self._translations = TranslationComponent(controls, 10)
        self._translations.name = 'TranslationComponent'
        self._translations.set_enabled(False)

    def _setup_main_modes(self):
        self._main_modes = ModesComponent(name='MainModes')
        self._main_modes.add_mode('Main', [
            self._mixer, self._mixer.main_layer, self._session,
            self._session_navigation
        ],
                                  cycle_mode_button_color='ModeButtons.Main')
        self._main_modes.add_mode('Select', [
            self._mixer, self._mixer.select_layer, self._session,
            self._session_navigation
        ],
                                  cycle_mode_button_color='ModeButtons.Select')
        self._main_modes.add_mode('Clips', [
            self._mixer, self._session, self._session.clips_layer,
            self._session_navigation
        ],
                                  cycle_mode_button_color='ModeButtons.Clips')
        self._main_modes.layer = Layer(priority=4,
                                       cycle_mode_button=self._grid[2][2])
        self._main_modes.selected_mode = 'Main'
        self._main_modes.set_enabled(False)

    def _can_auto_arm_track(self, track):
        routing = track.current_input_routing
        return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith(
            'DS1 Input')
class NoteEditorSettingsComponent(ModesComponent):
    initial_encoders = control_list(EncoderControl)
    encoders = control_list(EncoderControl)

    def __init__(self,
                 note_settings_component_class=None,
                 automation_component_class=None,
                 grid_resolution=None,
                 initial_encoder_layer=None,
                 encoder_layer=None,
                 *a,
                 **k):
        super(NoteEditorSettingsComponent, self).__init__(*a, **k)
        assert encoder_layer
        assert note_settings_component_class is not None
        assert automation_component_class is not None
        self.settings = note_settings_component_class(
            grid_resolution=grid_resolution, parent=self, is_enabled=False)
        self.automation = automation_component_class(parent=self,
                                                     is_enabled=False)
        self._mode_selector = ModeSelector(parent=self, is_enabled=False)
        self._visible_detail_view = b'Detail/DeviceChain'
        self._show_settings_task = self._tasks.add(
            task.sequence(task.wait(defaults.MOMENTARY_DELAY),
                          task.run(self._show_settings))).kill()
        self._update_infos_task = self._tasks.add(
            task.run(self._update_note_infos)).kill()
        self._settings_modes = ModesComponent(parent=self)
        self._settings_modes.set_enabled(False)
        self._settings_modes.add_mode(b'automation', [
            self.automation, self._mode_selector,
            partial(self._set_envelope_view_visible, True),
            partial(show_clip_view, self.application)
        ])
        self._settings_modes.add_mode(b'note_settings', [
            self.settings, self._update_note_infos, self._mode_selector,
            partial(self._set_envelope_view_visible, False),
            partial(show_clip_view, self.application)
        ])
        self._settings_modes.selected_mode = b'note_settings'
        self.__on_selected_setting_mode_changed.subject = self._settings_modes
        self.add_mode(b'disabled', [])
        self.add_mode(b'about_to_show', [
            AddLayerMode(self, initial_encoder_layer),
            (self._show_settings_task.restart, self._show_settings_task.kill)
        ])
        self.add_mode(b'enabled', [
            DetailViewRestorerMode(self.application),
            AddLayerMode(self, encoder_layer), self._settings_modes
        ])
        self.selected_mode = b'disabled'
        self._editors = []
        self._on_detail_clip_changed.subject = self.song.view
        self._on_selected_track_changed.subject = self.song.view
        self.__on_full_velocity_changed.subject = self.settings
        self.__on_setting_changed.subject = self.settings
        return

    automation_layer = forward_property(b'automation')(b'layer')
    mode_selector_layer = forward_property(b'_mode_selector')(b'layer')
    selected_setting = forward_property(b'_settings_modes')(b'selected_mode')

    @property
    def step_settings(self):
        return self._settings_modes

    @property
    def editors(self):
        return self._editors

    @listenable_property
    def is_touched(self):
        return any(
            imap(
                lambda e: e and e.is_touched,
                ifilter(lambda e: self._can_notify_is_touched(e),
                        self.encoders)))

    def _is_step_held(self):
        return len(self._active_note_regions()) > 0

    def add_editor(self, editor):
        assert editor != None
        self._editors.append(editor)
        self._on_active_note_regions_changed.add_subject(editor)
        self._on_notes_changed.replace_subjects(self._editors)
        self.__on_modify_all_notes_changed.add_subject(editor)
        return

    def set_encoders(self, encoders):
        self.encoders.set_control_element(encoders)
        self.settings.set_encoder_controls(encoders)
        self.automation.set_parameter_controls(encoders)

    @property
    def parameter_provider(self):
        self.automation.parameter_provider

    @parameter_provider.setter
    def parameter_provider(self, value):
        self.automation.parameter_provider = value

    @listens(b'selected_mode')
    def __on_selected_setting_mode_changed(self, mode):
        if mode == b'automation':
            self.automation.selected_time = self._active_note_regions()

    def update_view_state_based_on_selected_setting(self, setting):
        if self.selected_mode == b'enabled' and self.is_touched or setting is None:
            self._set_settings_view_enabled(False)
        elif self._is_step_held():
            if self.selected_setting == b'automation' and self.automation.can_automate_parameters or self.selected_setting == b'note_settings':
                self._show_settings()
        return

    @listens(b'full_velocity')
    def __on_full_velocity_changed(self):
        for editor in self._editors:
            editor.set_full_velocity()

    @listens(b'setting_changed')
    def __on_setting_changed(self, index, value):
        for editor in self._editors:
            self._modify_note_property_offset(editor, index, value)

    def _modify_note_property_offset(self, editor, index, value):
        if index == 1:
            editor.set_nudge_offset(value)
        elif index == 2:
            editor.set_length_offset(value)
        elif index == 3:
            editor.set_velocity_offset(value)

    def _set_envelope_view_visible(self, visible):
        clip = self.song.view.detail_clip
        if liveobj_valid(clip):
            if visible:
                clip.view.show_envelope()
            else:
                clip.view.hide_envelope()

    def _set_settings_view_enabled(self, should_show_view):
        really_show_view = should_show_view and self.automation.can_automate_parameters if self.selected_setting == b'automation' else should_show_view
        if really_show_view:
            if self.selected_mode == b'disabled':
                self.selected_mode = b'about_to_show'
        else:
            self._hide_settings()

    def _active_note_regions(self):
        all_active_regions = imap(lambda e: e.active_note_regions,
                                  self._editors)
        return list(set(chain.from_iterable(all_active_regions)))

    @listens_group(b'active_note_regions')
    def _on_active_note_regions_changed(self, _):
        if self.is_enabled():
            all_steps = self._active_note_regions()
            self.automation.selected_time = all_steps
            self._update_note_infos()
            self._set_settings_view_enabled(
                len(all_steps) > 0 and self.selected_setting != None
                or self.is_touched)
        return

    @listens_group(b'modify_all_notes')
    def __on_modify_all_notes_changed(self, editor):
        self.selected_mode = b'about_to_show' if editor.modify_all_notes_enabled else b'disabled'

    @listens_group(b'notes_changed')
    def _on_notes_changed(self, editor):
        self._update_infos_task.restart()

    @listens(b'detail_clip')
    def _on_detail_clip_changed(self):
        self.automation.clip = self.song.view.detail_clip if self.is_enabled(
        ) else None
        return

    @listens(b'selected_track')
    def _on_selected_track_changed(self):
        self.selected_mode = b'disabled'

    @initial_encoders.touched
    def initial_encoders(self, encoder):
        if self.selected_mode == b'about_to_show':
            self._show_settings()

    @initial_encoders.value
    def initial_encoders(self, encoder, value):
        if self.selected_mode == b'about_to_show':
            self._show_settings()

    @encoders.touched
    def encoders(self, encoder):
        if self._can_notify_is_touched(encoder):
            self.notify_is_touched()

    @encoders.released
    def encoders(self, encoder):
        if not self.is_touched and not self._is_step_held(
        ) and not self._is_edit_all_notes_active():
            self._hide_settings()
        if self._can_notify_is_touched(encoder):
            self.notify_is_touched()

    @encoders.value
    def encoders(self, encoder, value):
        self._notify_modification()

    def _can_notify_is_touched(self, encoder):
        if self.is_enabled():
            return self._settings_modes.selected_mode != b'note_settings' or encoder.index >= self.encoders.control_count - self.settings.number_of_settings
        return False

    def _is_edit_all_notes_active(self):
        return find_if(lambda e: e.modify_all_notes_enabled,
                       self._editors) != None

    def _notify_modification(self):
        for editor in self._editors:
            editor.notify_modification()

    def _update_note_infos(self):
        if self.settings.is_enabled():

            def min_max((l_min, l_max), (r_min, r_max)):
                return (min(l_min, r_min), max(l_max, r_max))

            all_min_max_attributes = filter(
                None, imap(lambda e: e.get_min_max_note_values(),
                           self._editors))
            min_max_values = [
                (99999, -99999)
            ] * 4 if len(all_min_max_attributes) > 0 else None
            for min_max_attribute in all_min_max_attributes:
                for i, attribute in enumerate(min_max_attribute):
                    min_max_values[i] = min_max(min_max_values[i], attribute)

            for i in xrange(4):
                self.settings.set_min_max(
                    i, min_max_values[i] if min_max_values else None)

            self.settings.set_info_message(
                b'Tweak to add note' if not self._is_edit_all_notes_active()
                and not min_max_values else b'')
        return
Example #28
0
class MonoInstrumentComponent(Component):

    _keypad_class = MonoScaleComponent
    _drumpad_class = MonoDrumpadComponent

    _scale_settings_component_class = ScaleTaggedSetting
    _toggle_settings_component_class = ToggledTaggedSetting

    _shifted = False

    def __init__(self,
                 script,
                 skin,
                 grid_resolution,
                 drum_group_finder,
                 device_provider,
                 parent_task_group,
                 settings=DEFAULT_INSTRUMENT_SETTINGS,
                 *a,
                 **k):
        super(MonoInstrumentComponent, self).__init__(*a, **k)
        self._settings = settings
        self._parent_task_group = parent_task_group
        self._scalenames = settings['ScaleNames']
        self._device_provider = device_provider
        self._script = script
        self._skin = skin
        self._grid_resolution = grid_resolution
        self._drum_group_finder = drum_group_finder

        self._setup_selected_session_control()

        self._setup_shift_mode()

        #self._scale_offset_component = self.register_component(self._scale_settings_component_class(name = 'VerticalOffset', attribute_tag = 'scale', parent_task_group = parent_task_group, value_dict = self._scalenames, default_value_index = self._scalenames.index(DEFAULT_SCALE), default_channel = 0, on_color = 'MonoInstrument.ScaleOffsetOnValue', off_color = 'MonoInstrument.ScaleOffsetOffValue'))
        self._scale_offset_component = self._scale_settings_component_class(
            parent=self,
            name='VerticalOffset',
            attribute_tag='scale',
            parent_task_group=parent_task_group,
            value_dict=self._scalenames,
            default_value_index=self._scalenames.index(DEFAULT_SCALE),
            default_channel=0,
            on_color='MonoInstrument.ScaleOffsetOnValue',
            off_color='MonoInstrument.ScaleOffsetOffValue')
        self._scale_offset_value.subject = self._scale_offset_component
        self.set_scale_up_button = self._scale_offset_component.up_button.set_control_element
        self.set_scale_down_button = self._scale_offset_component.down_button.set_control_element

        #self._mode_component = self.register_component(self._toggle_settings_component_class(name = 'SplitModeOffset', attribute_tag = 'mode', parent_task_group = parent_task_group,))
        self._mode_component = self._toggle_settings_component_class(
            parent=self,
            name='SplitModeOffset',
            attribute_tag='mode',
            parent_task_group=parent_task_group,
        )
        self._mode_value.subject = self._mode_component
        self.set_split_button = self._mode_component.split_toggle.set_control_element
        self.set_sequencer_button = self._mode_component.seq_toggle.set_control_element

        #self._keypad = self.register_component(self._keypad_class(parent = self, control_surface = script, skin = skin, grid_resolution = grid_resolution, parent_task_group = parent_task_group, settings = self._settings))
        self._keypad = self._keypad_class(parent=self,
                                          control_surface=script,
                                          skin=skin,
                                          grid_resolution=grid_resolution,
                                          parent_task_group=parent_task_group,
                                          settings=self._settings)
        self.set_vertical_offset_up_button = self._keypad._vertical_offset_component.up_button.set_control_element
        self.set_vertical_offset_down_button = self._keypad._vertical_offset_component.down_button.set_control_element
        self.set_offset_up_button = self._keypad._offset_component.up_button.set_control_element
        self.set_offset_down_button = self._keypad._offset_component.down_button.set_control_element
        self.set_octave_up_button = self._keypad._offset_component.bank_up_button.set_control_element
        self.set_octave_down_button = self._keypad._offset_component.bank_down_button.set_control_element

        #self._drumpad = self.register_component(self._drumpad_class(parent = self, control_surface = script, skin = skin, grid_resolution = grid_resolution, parent_task_group = parent_task_group, settings = self._settings))
        self._drumpad = self._drumpad_class(
            parent=self,
            control_surface=script,
            skin=skin,
            grid_resolution=grid_resolution,
            parent_task_group=parent_task_group,
            settings=self._settings)
        self.set_drum_offset_up_button = self._drumpad._drum_offset_component.up_button.set_control_element
        self.set_drum_offset_down_button = self._drumpad._drum_offset_component.down_button.set_control_element
        self.set_drum_octave_up_button = self._drumpad._drum_offset_component.bank_up_button.set_control_element
        self.set_drum_octave_down_button = self._drumpad._drum_offset_component.bank_down_button.set_control_element
        self.set_drumpad_mute_button = self._drumpad._drumgroup.mute_button.set_control_element
        self.set_drumpad_solo_button = self._drumpad._drumgroup.solo_button.set_control_element

        self._audio_loop = LoopSelectorComponent(follow_detail_clip=True,
                                                 measure_length=1.0,
                                                 name='Loop_Selector',
                                                 default_size=8)
        self.set_loop_selector_matrix = self._audio_loop.set_loop_selector_matrix

        #self._main_modes = self.register_component(ModesComponent())
        self._main_modes = ModesComponent()  #parent = self)
        self._main_modes.add_mode('disabled', [])
        self._main_modes.add_mode('audioloop', [self._audio_loop])
        self._main_modes.set_enabled(True)

        self._on_device_changed.subject = self._device_provider

        self.on_selected_track_changed.subject = self.song.view
        self.on_selected_track_changed()

    def _setup_selected_session_control(self):
        self._session_ring = SessionRingComponent(num_tracks=1, num_scenes=32)
        self._selected_session = ScaleSessionComponent(
            name="SelectedSession",
            session_ring=self._session_ring,
            auto_name=True,
            is_enabled=False)
        self._selected_session.set_enabled(False)

    def _setup_shift_mode(self):
        self._shifted = False
        #self._shift_mode = self.register_component(ModesComponent())
        self._shift_mode = ModesComponent()  #parent = self)
        self._shift_mode.add_mode('disabled', [])
        self._shift_mode.add_mode(
            'shift',
            tuple([
                lambda a: self._on_shift_value(True),
                lambda a: self._on_shift_value(False)
            ]),
            behaviour=ShiftCancellableBehaviourWithRelease())

    def set_shift_button(self, button):
        debug('shift_button:', button)
        self._on_shift_value.subject = button
        self._shifted = 0

    def set_shift_mode_button(self, button):
        self._on_shift_value.subject = None
        self._shifted = 0
        self._shift_mode.shift_button.set_control_element(button)

    @listens('value')
    def _on_shift_value(self, value):
        #debug('on shift value:', value)
        self._shifted = bool(value)
        self.update()

    def set_octave_enable_button(self, button):
        self._keypad._offset_component.shift_button.set_control_element(button)
        self._drumpad._drum_offset_component.shift_button.set_control_element(
            button)

    @listens('value')
    def _on_octave_enable_value(self, value):
        value and self._keypad._offset_component.shift_button._press_button(
        ) or self._keypad._offset_component.shift_button._release_button()
        value and self._drumpad._drum_offset_component.shift_button._press_button(
        ) or self._drumpad._drum_offset_component.shift_button._release_button(
        )

    @listens('value')
    def _mode_value(self, value):
        self.update()

    @listens('value')
    def _scale_offset_value(self, value):
        #debug('_scale_offset_value', value)
        value = self._settings['DefaultAutoScale'] if value is 'Auto' else value
        self._keypad._keygroup.scale = value
        self._scale_offset_component.buttons_are_pressed(
        ) and self._script.show_message('New scale is ' + str(value))
        self.update()

    @listens('instrument')
    def _on_drum_group_changed(self):
        drum_device = self._drum_group_finder.drum_group
        #debug('monoinstrument _on_drum_group_changed', drum_device)
        self._drumpad._step_sequencer.set_drum_group_device(drum_device)

    @listens('device')
    def _on_device_changed(self):
        #debug('monoinstrument _on_device_changed')
        self._script.schedule_message(1, self.update)
        #self.update()

    @listens('selected_track')
    def on_selected_track_changed(self):
        self._selected_session.update_current_track()
        self.update()

    def update(self):
        super(MonoInstrumentComponent, self).update()
        self._main_modes.selected_mode = 'disabled'
        #if self.is_enabled():
        new_mode = 'disabled'
        drum_device = find_drum_group_device(self.song.view.selected_track)
        #debug('instrument update, drum device:', drum_device.name if drum_device else None)
        self._drumpad._drumgroup.set_drum_group_device(drum_device)
        cur_track = self.song.view.selected_track
        if cur_track.has_audio_input and cur_track in self.song.visible_tracks:
            new_mode = 'audioloop'
        elif cur_track.has_midi_input:
            scale, mode = self._scale_offset_component.value, self._mode_component.value
            new_mode = get_instrument_type(cur_track, scale, self._settings)
            if mode is 'split':
                new_mode += '_split'
            elif mode is 'seq':
                new_mode += '_sequencer'
            if self._shifted:
                new_mode += '_shifted'
            self._script.set_feedback_channels(
                [self._scale_offset_component.channel])
            self._script.set_controlled_track(self.song.view.selected_track)
        #debug('trying to set mode:', new_mode)
        if new_mode in self._main_modes._mode_map or new_mode is None:
            self._main_modes.selected_mode = new_mode
            self._script.set_controlled_track(self.song.view.selected_track)
        else:
            self._main_modes.selected_mode = 'disabled'
            self._script.set_controlled_track(self.song.view.selected_track)
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'
Example #30
0
class Morph(ControlSurface):

    _model_name = 'Morph'
    bank_definitions = BANK_DEFINITIONS

    def __init__(self, c_instance, *a, **k):
        self.log_message = logger.info
        super(Morph, self).__init__(c_instance, *a, **k)
        self._skin = Skin(MorphColors)
        with self.component_guard():
            self._setup_controls()
            self._setup_background()
            #self._setup_button_background()
            self._setup_percussion_instrument_finder()
            self._setup_drum_group()
            self._setup_drum_group2()
            self._setup_keys_group()
            self._setup_piano_group()
            self._setup_autoarm()
            self._setup_device()
            self._setup_session()
            self._setup_session2()
            self._setup_session3()
            self._setup_mixer()
            self._setup_transport()
            self._setup_viewcontrol()
            self._setup_recorder()
            self._setup_translations()
            self._setup_modes()
        self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Morph ' + VERSION +
                         ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
        self.show_message('Morph ' + VERSION +
                          ' Control Surface Loaded, Autoarm is: ' +
                          ('ON' if AUTOARM else 'OFF'))
        self.schedule_message(2, self._init_surface)
        #debug('device:', self._device._get_device())

    def _init_surface(self):
        #self._main_modes.selected_mode = 'Main'
        self._on_device_changed.subject = self._device_provider
        self._on_selected_track_changed.subject = self.song.view
        self._on_selected_track_changed()
        self._send_midi(CHECK_MAPS)
        self._send_midi(MAGNET_VALUES_CALL)

    def port_settings_changed(self):
        super(Morph, self).port_settings_changed()
        self._init_surface()

    def _setup_controls(self):
        is_momentary = True
        optimized = False
        resource = ExclusiveResource  #PrioritizedResource
        self._pad_raw = [None for index in range(16)]
        self._pad = [[None, None, None, None] for index in range(4)]
        # for index in range(4):
        # 	self._pad[index] = [None, None, None, None]
        for chan in range(16):
            # debug('making ...', chan)
            self._pad_raw[chan] = [[
                ButtonElement(is_momentary=is_momentary,
                              msg_type=MIDI_NOTE_TYPE,
                              channel=chan,
                              identifier=MORPH_PADS[row][column],
                              name='Pad_' + str(column) + '_' + str(row) +
                              '_' + str(chan),
                              skin=self._skin,
                              resource_type=resource) for column in range(4)
            ] for row in range(4)]
            for row in self._pad_raw[chan]:
                for pad in row:
                    pad.enabled = False

        for proxy in range(16):
            buttons = []
            # debug('making pad ...', chan, proxy%4, math.floor(proxy/4))
            for chan in range(16):
                button = self._pad_raw[chan][int(proxy % 4)][int(
                    math.floor(proxy / 4))]
                buttons.append(button)
            self._pad[int(proxy % 4)][int(
                math.floor(proxy / 4))] = SpecialMultiElement(
                    buttons[0], buttons[1], buttons[2], buttons[3], buttons[4],
                    buttons[5], buttons[6], buttons[7], buttons[8], buttons[9],
                    buttons[10], buttons[11], buttons[12], buttons[13],
                    buttons[14], buttons[15])
            self._pad[int(proxy % 4)][int(math.floor(
                proxy / 4))]._name = 'PadCombo_' + str(proxy)
            # self.log_message('self._pad '+str(self._pad[int(proxy%4)][int(math.floor(proxy/4))]._name))
            # self.log_message('hasattr:'+ str(hasattr(self._pad[int(proxy%4)][int(math.floor(proxy/4))], '_name')))

        self._button = [
            ButtonElement(is_momentary=is_momentary,
                          msg_type=MIDI_NOTE_TYPE,
                          channel=CHANNEL,
                          identifier=MORPH_BUTTONS[index],
                          name='Button_' + str(index),
                          skin=self._skin,
                          resource_type=resource) for index in range(8)
        ]
        for button in self._button:
            button.set_enabled = True

        self._key_raw = [None for index in range(16)]
        self._key = [None for index in range(25)]
        for chan in range(16):

            self._key_raw[chan] = [
                MorphButtonElement(is_momentary=is_momentary,
                                   msg_type=MIDI_NOTE_TYPE,
                                   channel=chan,
                                   identifier=MORPH_KEYS[index],
                                   name='Key_' + str(index) + '_' + str(chan),
                                   skin=self._skin,
                                   resource_type=resource)
                for index in range(25)
            ]
            for key in self._key_raw[chan]:
                key.enabled = False

        for proxy in range(25):
            keys = []
            for chan in range(16):
                key = self._key_raw[chan][proxy]
                keys.append(key)
            self._key[proxy] = SpecialMultiElement(keys[0], keys[1], keys[2],
                                                   keys[3], keys[4], keys[5],
                                                   keys[6], keys[7], keys[8],
                                                   keys[9], keys[10], keys[11],
                                                   keys[12], keys[13],
                                                   keys[14], keys[15])
            self._key[proxy]._name = 'KeyCombo_' + str(proxy)

        self._dials = [
            MorphEncoderElement(msg_type=MIDI_CC_TYPE,
                                channel=CHANNEL,
                                identifier=MORPH_DIALS[index],
                                map_mode=Live.MidiMap.MapMode.absolute,
                                name='Dial_' + str(index),
                                resource_type=resource) for index in range(8)
        ]
        self._slider = [
            MorphEncoderElement(msg_type=MIDI_CC_TYPE,
                                channel=CHANNEL,
                                identifier=MORPH_SLIDERS[index],
                                map_mode=Live.MidiMap.MapMode.absolute,
                                name='Slider_' + str(index),
                                resource_type=resource) for index in range(2)
        ]
        self._send_pressure = [
            MorphEncoderElement(msg_type=MIDI_CC_TYPE,
                                channel=CHANNEL,
                                identifier=MORPH_SEND_PRESSURE[index],
                                map_mode=Live.MidiMap.MapMode.absolute,
                                name='SendPressure_' + str(index),
                                resource_type=resource) for index in range(2)
        ]
        self._thunder_slider = [
            MorphEncoderElement(msg_type=MIDI_CC_TYPE,
                                channel=CHANNEL,
                                identifier=MORPH_THUNDER_SLIDERS[index],
                                map_mode=Live.MidiMap.MapMode.absolute,
                                name='Slider_' + str(index),
                                resource_type=resource) for index in range(6)
        ]

        self._pad_matrix = ButtonMatrixElement(name='PadMatrix',
                                               rows=self._pad)
        self._dial_matrix = ButtonMatrixElement(name='DialMatrix',
                                                rows=[self._dials])
        self._button_matrix = ButtonMatrixElement(name='ButtonMatrix',
                                                  rows=[self._button])
        self._key_matrix = ButtonMatrixElement(name='KeyMatrix',
                                               rows=[self._key[:14]])
        self._key_shift_matrix = ButtonMatrixElement(name='KeyShiftMatrix',
                                                     rows=[self._key[2:11]])
        self._slider_matrix = ButtonMatrixElement(name='SliderMatrix',
                                                  rows=[self._slider])
        self._send_pressure_matrix = ButtonMatrixElement(
            name='SendAMatrix', rows=[self._send_pressure])
        self._thunder_slider_matrix = ButtonMatrixElement(
            name='ThunderSliderMatrix', rows=[self._thunder_slider])
        #self._shift_send_pressure_matrix = ButtonMatrixElement(name = 'ShiftSendMatrix', rows = [ [None, None, self._send_pressure[0], self._send_pressure[1]] ])

        self._piano_button = [
            MorphButtonElement(is_momentary=is_momentary,
                               msg_type=MIDI_NOTE_TYPE,
                               channel=CHANNEL,
                               identifier=PIANO_BUTTONS[index],
                               name='PianoButton_' + str(index),
                               skin=self._skin,
                               resource_type=resource) for index in range(4)
        ]
        for button in self._piano_button:
            button.enabled = False
        #self._piano_key = [MorphButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = PIANO_CHANNEL, identifier = PIANO_KEYS[index], name = 'PianoKey_' + str(index), skin = self._skin, resource_type = resource) for index in range(25)]

        self._piano_matrix = ButtonMatrixElement(name='PianoMatrix',
                                                 rows=[self._key])
        self._piano_session_matrix = ButtonMatrixElement(
            name='PianoSessionMatrix',
            rows=[
                self._key[0:4], self._key[4:8], self._key[8:12],
                self._key[12:16]
            ])
        #self._drum_session_matrix = ButtonMatrixElement(name = 'DrumSessionMatrix', rows = )

    def _setup_background(self):
        self._background = BackgroundComponent()
        self._background.layer = Layer(priority=1,
                                       pads=self._pad_matrix,
                                       buttons=self._button_matrix,
                                       keys=self._key_matrix,
                                       dials=self._dial_matrix,
                                       sliders=self._slider_matrix)
        self._background.set_enabled(False)

    def _setup_percussion_instrument_finder(self):
        self._percussion_instrument_finder = PercussionInstrumentFinder(
            device_parent=self.song.view.selected_track)

    def _setup_drum_group(self):
        # self._drum_group = MorphDrumGroup(set_pad_translations = self.set_pad_translations, translation_channel = PAD_TRANSLATION_CHANNEL)
        self._drum_group = MorphDrumGroup()
        self._drum_group.position = 9
        self._drum_group.main_layer = AddLayerMode(
            self._drum_group, Layer(priority=2, matrix=self._pad_matrix))
        self._drum_group.nav_layer = AddLayerMode(
            self._drum_group,
            Layer(priority=2,
                  scroll_up_button=self._key[1],
                  scroll_down_button=self._key[0]))
        self._drum_group.set_enabled(False)

    def _setup_drum_group2(self):
        # self._drum_group2 = MorphDrumGroup(set_pad_translations = self.set_pad_translations, translation_channel = DRUM_TRANSLATION_CHANNEL)
        self._drum_group2 = MorphDrumGroup()
        self._drum_group2.position = 9
        self._drum_group2.main_layer = AddLayerMode(
            self._drum_group2, Layer(priority=2, matrix=self._pad_matrix))
        self._drum_group2.nav_layer = AddLayerMode(
            self._drum_group2,
            Layer(priority=2,
                  scroll_up_button=self._key[1],
                  scroll_down_button=self._key[0]))
        self._drum_group2.set_enabled(False)

    def _setup_keys_group(self):
        # self._keys_group = MorphKeysGroup(translation_channel = KEY_TRANSLATION_CHANNEL)
        self._keys_group = MorphKeysGroup()
        self._keys_group.main_layer = AddLayerMode(
            self._keys_group, Layer(priority=2, matrix=self._key_matrix))
        self._keys_group.shift_layer = AddLayerMode(
            self._keys_group,
            Layer(priority=2,
                  matrix=self._key_shift_matrix,
                  scroll_up_button=self._key[12],
                  scroll_down_button=self._key[11]))
        self._keys_group.set_enabled(False)

    def _setup_piano_group(self):
        # self._piano_group = MorphKeysGroup(translation_channel = PIANO_TRANSLATION_CHANNEL)
        self._piano_group = MorphKeysGroup()
        self._piano_group._hi_limit = 8
        self._piano_group.main_layer = AddLayerMode(
            self._piano_group,
            Layer(priority=2,
                  matrix=self._piano_matrix,
                  scroll_up_button=self._piano_button[1],
                  scroll_down_button=self._piano_button[0]))
        #self._piano_group.shift_layer = AddLayerMode(self._piano_group, Layer(matrix = self._piano_shift_matrix, scroll_up_button = self._pian0[12], scroll_down_button = self._key[11]))
        self._piano_group.set_enabled(False)

    def _setup_autoarm(self):
        self._auto_arm = AutoArmComponent(name='Auto_Arm', is_enabled=AUTOARM)
        self._auto_arm.can_auto_arm_track = self._can_auto_arm_track
        self._auto_arm._update_notification = lambda: None

    def _setup_transport(self):
        self._transport = TransportComponent(name='Transport')
        self._transport.layer = Layer(priority=2,
                                      play_button=self._button[4],
                                      stop_button=self._button[5],
                                      overdub_button=self._button[6])
        self._transport.set_enabled(False)

    def _setup_translations(self):
        self._translations = TranslationComponent(name='Translations',
                                                  channel=USER_CHANNEL,
                                                  controls=self._dials +
                                                  self._slider)
        self._translations.set_enabled(False)

    def _setup_device(self):
        self._device = MorphDeviceComponent(
            device_decorator_factory=DeviceDecoratorFactory(),
            banking_info=BankingInfo(self.bank_definitions),
            device_provider=self._device_provider,
            device_bank_registry=DeviceBankRegistry())
        self._device_parameters = DeviceParameterComponent(self._device)
        self._device_parameters.layer = Layer(
            priority=2, parameter_controls=self._dial_matrix)
        self._device.set_enabled(False)
        self._device_parameters.set_enabled(False)

        self._device2 = MorphDeviceComponent(
            device_decorator_factory=DeviceDecoratorFactory(),
            banking_info=BankingInfo(self.bank_definitions),
            device_provider=self._device_provider,
            device_bank_registry=DeviceBankRegistry())
        self._device_parameters2 = DeviceParameterComponent(self._device2)
        self._device_parameters2.layer = Layer(
            priority=2, parameter_controls=self._thunder_slider_matrix)
        self._device2.set_enabled(False)
        self._device_parameters2.set_enabled(False)

    def _setup_session(self):
        self._session_ring = SessionRingComponent(name='Session_Ring',
                                                  num_tracks=4,
                                                  num_scenes=4)

        self._session = SessionComponent(name='Session',
                                         session_ring=self._session_ring,
                                         auto_name=True)
        self._session.layer = Layer(
            priority=2,
            clip_launch_buttons=self._pad_matrix,
        )  # stop_all_clips_button = self._button[5])
        self._session.set_enabled(False)

        self._session_navigation = SessionNavigationComponent(
            name='Session_Navigation', session_ring=self._session_ring)
        self._session_navigation.layer = Layer(priority=2,
                                               left_button=self._button[0],
                                               right_button=self._button[1])
        self._session_navigation.set_enabled(False)

    def _setup_session2(self):
        self._session2 = SessionComponent(name='Session2',
                                          session_ring=self._session_ring,
                                          auto_name=True)
        self._session2.layer = Layer(
            priority=2, clip_launch_buttons=self._piano_session_matrix)
        self._session2.set_enabled(False)

    def _setup_session3(self):
        self._session3 = SessionComponent(name='Session3',
                                          session_ring=self._session_ring,
                                          auto_name=True)
        self._session3.layer = Layer(priority=2,
                                     clip_launch_buttons=self._pad_matrix)
        self._session3.set_enabled(False)

    def _setup_mixer(self):
        self._mixer = MorphMixerComponent(
            tracks_provider=self._session_ring,
            track_assigner=SimpleTrackAssigner(),
            auto_name=True,
            invert_mute_feedback=False,
            channel_strip_component_type=MorphChannelStripComponent)
        self._mixer._selected_strip.main_layer = AddLayerMode(
            self._mixer._selected_strip,
            Layer(priority=2, send_controls=self._send_pressure_matrix))
        self._mixer._selected_strip.shift_layer = AddLayerMode(
            self._mixer._selected_strip,
            Layer(priority=2, stop_button=self._button[5]))
        #self._mixer._selected_strip.shift_layer = AddLayerMode(self._mixer, Layer(send_controls = self._shift_send_pressure_matrix.submatrix[:,]))

    def _setup_viewcontrol(self):
        self._viewcontrol = ViewControlComponent()
        self._viewcontrol.layer = Layer(priority=2,
                                        prev_track_button=self._button[0],
                                        next_track_button=self._button[1])
        self._viewcontrol.set_enabled(False)

    def _setup_recorder(self):
        self._recorder = SessionRecordingComponent(
            view_controller=ViewControlComponent())
        self._recorder.layer = Layer(priority=2, record_button=self._button[6])
        self._recorder.set_enabled(False)

    def _assign_crossfader(self):
        self._slider[1].connect_to(
            self.song.master_track.mixer_device.crossfader)
        # debug('_assign_crossfader:', self._slider[1]._parameter_to_map_to)

    def _deassign_crossfader(self):
        self._slider[1].release_parameter()
        # debug('_assign_crossfader:', self._slider[1]._parameter_to_map_to)

    def _setup_modes(self):
        self._production_modes = ModesComponent(name='ProductionModes')
        self._production_modes.add_mode('Main', [
            self._mixer, self._mixer._selected_strip.main_layer,
            self._viewcontrol, self._drum_group, self._drum_group.main_layer,
            self._keys_group, self._keys_group.main_layer, self._device,
            self._device_parameters, self._transport, self._assign_crossfader
        ])
        self._production_modes.add_mode('Shift', [
            self._mixer, self._mixer._selected_strip.shift_layer,
            self._session, self._session_navigation, self._drum_group,
            self._drum_group.nav_layer, self._keys_group,
            self._keys_group.shift_layer, self._deassign_crossfader,
            self._recorder, self._translations
        ],
                                        behaviour=MomentaryBehaviour())
        self._production_modes.layer = Layer(Shift_button=self._button[7])
        self._production_modes.selected_mode = 'Main'
        self._production_modes.set_enabled(False)

        self._piano_modes = ModesComponent(name='PianoModes')
        self._piano_modes.add_mode('Main', [
            self._piano_group, self._piano_group.main_layer, self._mixer,
            self._mixer._selected_strip.main_layer, self._viewcontrol,
            self._device, self._device_parameters, self._transport,
            self._assign_crossfader
        ])
        self._piano_modes.add_mode('Shift', [
            self._mixer, self._mixer._selected_strip.shift_layer,
            self._session2, self._session_navigation, self._recorder
        ],
                                   behaviour=MomentaryBehaviour())
        self._piano_modes.layer = Layer(Shift_button=self._button[7])
        self._piano_modes.selected_mode = 'Main'
        self._piano_modes.set_enabled(False)

        self._drumpad_modes = ModesComponent(name='DrumpadModes')
        self._drumpad_modes.add_mode('Main', [
            self._mixer, self._mixer._selected_strip.main_layer,
            self._viewcontrol, self._drum_group2, self._drum_group2.main_layer,
            self._transport, self._assign_crossfader
        ])
        self._drumpad_modes.add_mode('Shift', [
            self._mixer, self._mixer._selected_strip.shift_layer,
            self._session3, self._session_navigation, self._recorder
        ],
                                     behaviour=MomentaryBehaviour())
        self._drumpad_modes.layer = Layer(Shift_button=self._button[7])
        self._drumpad_modes.selected_mode = 'Main'
        self._drumpad_modes.set_enabled(False)

        self._thunder_modes = ModesComponent(name='ThunderModes')
        self._thunder_modes.add_mode('Main', [
            self._mixer, self._mixer._selected_strip.main_layer,
            self._viewcontrol, self._transport, self._assign_crossfader,
            self._device2, self._device_parameters2
        ])
        self._thunder_modes.add_mode('Shift', [
            self._mixer, self._mixer._selected_strip.shift_layer,
            self._recorder, self._device2, self._device_parameters2
        ],
                                     behaviour=MomentaryBehaviour())
        self._thunder_modes.layer = Layer(Shift_button=self._button[7])
        self._thunder_modes.selected_mode = 'Main'
        self._thunder_modes.set_enabled(False)

        self._innovator_modes = ModesComponent(name='InnovatorModes')
        self._innovator_modes.add_mode('Main', [
            self._mixer, self._mixer._selected_strip.main_layer,
            self._viewcontrol, self._device, self._device_parameters,
            self._transport, self._assign_crossfader
        ])
        self._innovator_modes.add_mode('Shift', [
            self._mixer, self._mixer._selected_strip.shift_layer,
            self._deassign_crossfader, self._recorder, self._translations
        ],
                                       behaviour=MomentaryBehaviour())
        self._innovator_modes.layer = Layer(Shift_button=self._button[7])
        self._innovator_modes.selected_mode = 'Main'
        self._innovator_modes.set_enabled(False)

        self._main_modes = ModesComponent(name='MainModes')
        self._main_modes.add_mode('disabled', self._background)
        self._main_modes.add_mode('ProductionMode', [self._production_modes])
        self._main_modes.add_mode('PianoMode', [self._piano_modes])
        self._main_modes.add_mode('DrumpadMode', [self._drumpad_modes])
        self._main_modes.add_mode('ThunderMode', [self._thunder_modes])
        self._main_modes.add_mode('InnovatorMode', [self._innovator_modes])

        self._report_mode.subject = self._main_modes
        self._main_modes.selected_mode = 'disabled'

    @listens('selected_mode')
    def _report_mode(self, *a, **k):
        debug('Modes:', self._main_modes.selected_mode,
              self._production_modes.selected_mode,
              self._piano_modes.selected_mode,
              self._drumpad_modes.selected_mode,
              self._thunder_modes.selected_mode)

    def _maintestfunc(self, *a, **k):
        debug('maintestfunc')

    def _can_auto_arm_track(self, track):
        if not AUTOARM:
            return False
        routing = track.current_input_routing
        return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith(
            'Sensel') or routing.startswith('Morph')

    @listens('device')
    def _on_device_changed(self):
        debug('_on_device_changed:', self._device_provider.device)
        self._on_selected_track_changed()
        # self._drum_group.set_drum_group_device(self._device_provider.device)
        # self._drum_group2.set_drum_group_device(self._device_provider.device)

    @listens('selected_track')
    def _on_selected_track_changed(self):
        debug('_on_selected_track_changed')
        track = self.song.view.selected_track
        self._percussion_instrument_finder.device_parent = track
        self._percussion_instrument_finder.update()
        self._drum_group.set_drum_group_device(
            self._percussion_instrument_finder.drum_group)
        self._drum_group2.set_drum_group_device(
            self._percussion_instrument_finder.drum_group)

    def disconnect(self):
        self.log_message(
            '<<<<<<<<<<<<<<<<<<<<<<<<< Morph log closed >>>>>>>>>>>>>>>>>>>>>>>>>'
        )
        super(Morph, self).disconnect()

    def process_midi_bytes(self, midi_bytes, midi_processor):
        super(Morph, self).process_midi_bytes(midi_bytes, midi_processor)
        if midi.is_sysex(midi_bytes):
            self.handle_sysex(midi_bytes)

    def handle_sysex(self, midi_bytes):
        debug('sysex: ', str(midi_bytes))
        #debug('matching:', midi_bytes[1:5], 'to', tuple([0, 1, 97]  + [self._sysex_id]))
        if len(midi_bytes) == 9 and midi_bytes[1:5] == tuple([0, 1, 97] +
                                                             [self._sysex_id]):
            if not self._connected:
                #debug('connecting from sysex...')
                self._connected = True
                self._initialize_hardware()
                self._initialize_script()
        if len(midi_bytes) == 11:
            if midi_bytes == PIANO_OVERLAY:
                debug('piano overlay...')
                self._main_modes.selected_mode = 'PianoMode'
            elif midi_bytes == PRODUCTION_OVERLAY:
                debug('production overlay...')
                self._main_modes.selected_mode = 'ProductionMode'
            elif midi_bytes == DRUM_OVERLAY:
                debug('drum overlay...')
                self._main_modes.selected_mode = 'DrumpadMode'
            elif midi_bytes == THUNDER_OVERLAY:
                debug('thunder overlay...')
                self._main_modes.selected_mode = 'ThunderMode'
            elif midi_bytes == INNOVATOR_OVERLAY:
                debug('innovator overlay...')
                self._main_modes.selected_mode = 'InnovatorMode'
            elif midi_bytes == NO_OVERLAY:
                debug('no overlay...')
                self._main_modes.selected_mode = 'InnovatorMode'
Example #31
0
class OhmModes(LividControlSurface):

    _sysex_id = 2
    _alt_sysex_id = 7
    _model_name = 'Ohm'
    _version_check = 'b996'
    _host_name = 'Ohm'
    device_provider_class = ModDeviceProvider

    def __init__(self, c_instance):
        super(OhmModes, self).__init__(c_instance)
        self._skin = Skin(OhmColors)
        with self.component_guard():
            self._define_sysex()
            self._setup_controls()
            self._setup_background()
            self._setup_m4l_interface()
            self._setup_translations()
            self._setup_session_control()
            self._setup_mixer_control()
            self._setup_device_control()
            self._setup_transport_control()
            self._setup_drumgroup()
            self._setup_keygroup()
            self._setup_bassgroup()
            self._setup_mod()
            self._setup_modswitcher()
            self._setup_modes()
        self._on_device_changed.subject = self._device_provider

    def _define_sysex(self):
        #self._send_midi(tuple(switchxfader))
        self._reverse_crossfader = SendLividSysexMode(
            self._livid_settings, call='reverse crossfader', message=[1])

    def update_display(self):
        super(OhmModes, self).update_display()
        #self.strobe()

    def _initialize_hardware(self):
        super(OhmModes, self)._initialize_hardware()
        #self._reverse_crossfader.enter_mode()

    def _initialize_script(self):
        super(OhmModes, self)._initialize_script()
        self._main_modes.selected_mode = 'Mix'
        self._session.update()
        self._mixer.update()

    def _setup_controls(self):
        is_momentary = True
        optimized = True
        resource = PrioritizedResource
        self._fader = [
            MonoEncoderElement(msg_type=MIDI_CC_TYPE,
                               channel=CHANNEL,
                               identifier=OHM_FADERS[index],
                               name='Fader_' + str(index),
                               num=index,
                               script=self,
                               optimized_send_midi=optimized,
                               resource_type=resource) for index in range(8)
        ]
        self._button = [
            MonoButtonElement(is_momentary=is_momentary,
                              msg_type=MIDI_NOTE_TYPE,
                              channel=CHANNEL,
                              identifier=OHM_BUTTONS[index],
                              name='Button_' + str(index),
                              script=self,
                              skin=self._skin,
                              optimized_send_midi=optimized,
                              resource_type=resource) for index in range(8)
        ]
        self._dial = [
            MonoEncoderElement(msg_type=MIDI_CC_TYPE,
                               channel=CHANNEL,
                               identifier=OHM_DIALS[index],
                               name='Encoder_' + str(index),
                               num=index,
                               script=self,
                               optimized_send_midi=optimized,
                               resource_type=resource) for index in range(16)
        ]
        self._menu = [
            MonoButtonElement(is_momentary=is_momentary,
                              msg_type=MIDI_NOTE_TYPE,
                              channel=CHANNEL,
                              identifier=OHM_MENU[index],
                              name='Menu_' + str(index),
                              script=self,
                              skin=self._skin,
                              optimized_send_midi=optimized,
                              resource_type=resource) for index in range(6)
        ]
        self._crossfader = MonoEncoderElement(msg_type=MIDI_CC_TYPE,
                                              channel=CHANNEL,
                                              identifier=CROSSFADER,
                                              name='Crossfader',
                                              script=self,
                                              optimized_send_midi=optimized,
                                              resource_type=resource)
        self._livid = MonoButtonElement(is_momentary=is_momentary,
                                        msg_type=MIDI_NOTE_TYPE,
                                        channel=CHANNEL,
                                        identifier=LIVID,
                                        name='Livid_Button',
                                        skin=self._skin,
                                        script=self,
                                        optimized_send_midi=optimized,
                                        resource_type=resource)
        self._shift_l = MonoButtonElement(is_momentary=is_momentary,
                                          msg_type=MIDI_NOTE_TYPE,
                                          channel=CHANNEL,
                                          identifier=SHIFT_L,
                                          name='Page_Button_Left',
                                          script=self,
                                          skin=self._skin,
                                          optimized_send_midi=optimized,
                                          resource_type=resource)
        self._shift_r = MonoButtonElement(is_momentary=is_momentary,
                                          msg_type=MIDI_NOTE_TYPE,
                                          channel=CHANNEL,
                                          identifier=SHIFT_R,
                                          name='Page_Button_Right',
                                          script=self,
                                          skin=self._skin,
                                          optimized_send_midi=optimized,
                                          resource_type=resource)
        self._grid = [[
            MonoButtonElement(is_momentary=is_momentary,
                              msg_type=MIDI_NOTE_TYPE,
                              channel=CHANNEL,
                              identifier=column * 8 + row,
                              name='Grid_' + str(column + (row * 8)),
                              script=self,
                              skin=self._skin,
                              optimized_send_midi=optimized,
                              resource_type=resource) for column in range(8)
        ] for row in range(8)]
        self._matrix = ButtonMatrixElement(
            name='Matrix',
            rows=[[self._grid[row][column] for column in range(8)]
                  for row in range(8)])
        self._dial_matrix = ButtonMatrixElement(
            name='DialMatrix',
            rows=[self._dial[index * 4:(index * 4) + 4] for index in range(4)])
        self._menu_matrix = ButtonMatrixElement(name='MenuMatrix',
                                                rows=[self._menu])
        self._fader_matrix = ButtonMatrixElement(name='FaderMatrix',
                                                 rows=[self._fader])
        self._button_matrix = ButtonMatrixElement(name='ButtonMatrix',
                                                  rows=[self._button])

        self._parameter_controls = ButtonMatrixElement(
            rows=[self._dial[:4], self._dial[4:8]])

    def _setup_background(self):
        self._background = BackgroundComponent(name='Background')
        self._background.layer = Layer(
            priority=3,
            matrix=self._matrix.submatrix[:, :],
            livid_button=self._livid,
            shift_l_button=self._shift_l,
            shift_r_button=self._shift_r,
            crossfader=self._crossfader,
            dial_matrix=self._dial_matrix.submatrix[:, :],
            menu_matrix=self._menu_matrix.submatrix[:, :],
            fader_matrix=self._fader_matrix.submatrix[:, :],
            button_matrix=self._button_matrix.submatrix[:, :])
        self._background.set_enabled(False)

    def _setup_m4l_interface(self):
        self._m4l_interface = M4LInterfaceComponent(
            controls=self.controls, component_guard=self.component_guard)
        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 _setup_translations(self):
        controls = []
        for array in self._grid:
            for button in array:
                controls.append(button)
        if FADER_BANKING:
            controls = controls + self._dial
        if DIAL_BANKING:
            controls = controls + self._dial
        self._translations = TranslationComponent(
            controls=controls, user_channel_offset=USER_CHANNEL, channel=8)
        self._translations.layer = Layer(
            priority=5,
            channel_selector_buttons=self._menu_matrix.submatrix[:, :])
        self._translations.set_enabled(False)

        dj_controls = [self._grid[7][index] for index in range(7)]
        self._dj_translation = TranslationComponent(controls=dj_controls,
                                                    channel=12)

    def _setup_session_control(self):
        self._session_ring = SessionRingComponent(num_tracks=7, num_scenes=5)
        self._session_ring.set_enabled(True)

        self._session_navigation = SessionNavigationComponent(
            session_ring=self._session_ring)
        self._session_navigation.scroll_navigation_layer = AddLayerMode(
            self._session_navigation,
            Layer(priority=5,
                  up_button=self._menu[2],
                  down_button=self._menu[5],
                  left_button=self._menu[3],
                  right_button=self._menu[4]))
        self._session_navigation.page_navigation_layer = AddLayerMode(
            self._session_navigation,
            Layer(priority=5,
                  page_up_button=self._menu[2],
                  page_down_button=self._menu[5],
                  page_left_button=self._menu[3],
                  page_right_button=self._menu[4]))
        self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._vertical_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
        self._session_navigation._vertical_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
        self._session_navigation._horizontal_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
        self._session_navigation._horizontal_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
        self._session_navigation.set_enabled(False)

        self._session = OhmSessionComponent(name='Session',
                                            session_ring=self._session_ring,
                                            auto_name=True)
        hasattr(self._session,
                '_enable_skinning') and self._session._enable_skinning()
        self._session.set_enabled(False)
        self._session.clip_launch_layer = AddLayerMode(
            self._session,
            Layer(priority=5,
                  clip_launch_buttons=self._matrix.submatrix[:7, :5]))
        self._session.scene_launch_layer = AddLayerMode(
            self._session,
            Layer(priority=5,
                  scene_launch_buttons=self._matrix.submatrix[7, :5]))

        self._session_zoom = SessionOverviewComponent(
            name='Session_Overview',
            session_ring=self._session_ring,
            enable_skinning=True)
        self._session_zoom.layer = Layer(
            priority=5, button_matrix=self._matrix.submatrix[:7, :5])
        self._session_zoom.set_enabled(False)

        self._session_modes = ModesComponent(name='Session_Modes')
        self._session_modes.add_mode('disabled', [
            self._session, self._session.clip_launch_layer,
            self._session.scene_launch_layer, self._session_navigation,
            self._session_navigation.scroll_navigation_layer
        ])
        self._session_modes.add_mode('enabled', [
            self._session, self._session.scene_launch_layer,
            self._session_zoom, self._session_navigation,
            self._session_navigation.page_navigation_layer
        ],
                                     behaviour=DefaultedBehaviour())
        self._session_modes.layer = Layer(priority=5,
                                          enabled_button=self._grid[7][7])
        self._session_modes.selected_mode = 'disabled'
        self._session_modes.set_enabled(False)

    def _setup_mixer_control(self):
        self._mixer = OhmMixerComponent(
            name='Mixer',
            tracks_provider=self._session_ring,
            track_assigner=SimpleTrackAssigner(),
            invert_mute_feedback=True,
            auto_name=True,
            enable_skinning=True,
            channel_strip_component_type=MonoChannelStripComponent)
        self._mixer.layer = Layer(
            priority=5,
            volume_controls=self._fader_matrix.submatrix[:7, :],
            prehear_volume_control=self._dial[15],
            crossfader_control=self._crossfader)
        self._mixer.master_strip().layer = Layer(priority=5,
                                                 volume_control=self._fader[7],
                                                 select_button=self._button[7])
        self._mixer.mix_layer = AddLayerMode(
            self._mixer,
            Layer(
                priority=5,
                mute_buttons=self._matrix.submatrix[:7, 5],
                solo_buttons=self._matrix.submatrix[:7, 6],
                arm_buttons=self._matrix.submatrix[:7, 7],
                send_controls=self._dial_matrix.submatrix[:, :2],
                pan_controls=self._dial_matrix.submatrix[:7, 2:],
                track_select_buttons=self._button_matrix.submatrix[:7, :],
            ))
        self._mixer.dj_layer = AddLayerMode(
            self._mixer,
            Layer(
                priority=5,
                mute_buttons=self._matrix.submatrix[:7, 5],
                crossfade_toggles=self._matrix.submatrix[:7, 6],
                end_pan_controls=self._dial_matrix.submatrix[:3, 3],
                eq_gain_controls=self._dial_matrix.submatrix[:, :3],
                track_select_buttons=self._button_matrix.submatrix[:7, :],
            ))
        self._mixer.instrument_layer = AddLayerMode(
            self._mixer,
            Layer(priority=5,
                  instrument_send_controls=self._dial_matrix.submatrix[:, 2:],
                  arming_track_select_buttons=self._button_matrix.
                  submatrix[:7, :]))

    def _setup_device_control(self):
        self._device = OhmDeviceComponent(
            script=self,
            name='Device_Component',
            device_provider=self._device_provider,
            device_bank_registry=DeviceBankRegistry())
        self._device.layer = Layer(priority=5,
                                   parameter_controls=self._parameter_controls)
        self._device.set_enabled(False)

        self._device_navigator = DeviceNavigator(
            self._device_provider,
            self._mixer,
            self,
            name='Device_Navigator',
        )
        self._device_navigator.layer = Layer(priority=5,
                                             prev_button=self._menu[3],
                                             next_button=self._menu[4])
        self._device_navigator.set_enabled(False)

    def _setup_transport_control(self):
        self._transport = OhmTransportComponent()
        self._transport.name = 'Transport'
        self._transport.layer = Layer(priority=5,
                                      play_button=self._menu[0],
                                      stop_button=self._menu[1])
        self._transport.set_enabled(False)

    def _setup_drumgroup(self):
        self._drumgroup = MonoDrumGroupComponent(
            translation_channel=PAGE1_DRUM_CHANNEL,
            set_pad_translations=self.set_pad_translations)
        self._drumgroup._on_selected_track_changed.subject = None
        self._drumgroup.translation_channel = PAGE1_DRUM_CHANNEL
        self._drumgroup.layer = Layer(priority=6,
                                      matrix=self._matrix.submatrix[:4, :4])
        self._drumgroup.set_enabled(False)

    def _setup_keygroup(self):
        self._scale_mode = ModesComponent(name='ScaleMode')
        for scale in SCALES:
            debug('making scale mode:', scale, str(scale))
            self._scale_mode.add_mode(str(scale), [])
        self._scale_mode.layer = Layer(priority=5,
                                       ionian_button=self._grid[7][0],
                                       dorian_button=self._grid[7][1],
                                       phrygian_button=self._grid[7][2],
                                       lydian_button=self._grid[7][3],
                                       mixolydian_button=self._grid[7][4],
                                       aeolian_button=self._grid[7][5],
                                       locrian_button=self._grid[7][6],
                                       major_button=self._grid[7][7])
        self._scale_mode.selected_mode = 'ionian'
        self._scale_mode.set_enabled(False)
        self._on_scale_change.subject = self._scale_mode

        self._octave_offset_component = ScrollingChannelizedSettingsComponent(
            name='NoteOffset',
            parent_task_group=self._task_group,
            value_dict=range(104),
            default_value_index=36,
            default_channel=0,
            bank_increment=12,
            bank_on_color='MonoInstrument.OffsetOnValue',
            bank_off_color='MonoInstrument.OffsetOffValue')
        self._octave_offset_component.layer = Layer(
            priority=5,
            bank_up_button=self._menu[2],
            bank_down_button=self._menu[5])
        self._on_octave_change.subject = self._octave_offset_component

        self._keygroup = OhmKeyGroupComponent()
        self._keygroup._on_selected_track_changed.subject = None
        self._keygroup.translation_channel = PAGE1_KEYS_CHANNEL
        self._keygroup.layer = Layer(priority=6,
                                     matrix=self._matrix.submatrix[:, 4:7])
        self._keygroup.set_enabled(False)

    def _setup_bassgroup(self):
        self._bassgroup = OhmBassGroupComponent()
        self._bassgroup._on_selected_track_changed.subject = None
        self._bassgroup.translation_channel = PAGE1_BASS_CHANNEL
        self._bassgroup.layer = Layer(priority=6,
                                      matrix=self._matrix.submatrix[4:, :4])
        self._bassgroup.set_enabled(False)

    def _setup_mod(self):
        self.monomodular = get_monomodular(self)
        self.monomodular.name = 'monomodular_switcher'
        self.modhandler = OhmModHandler(script=self,
                                        device_provider=self._device_provider)
        self.modhandler.name = 'ModHandler'
        self.modhandler.layer = Layer(
            priority=5,
            grid=self._matrix.submatrix[:, :],
            nav_up_button=self._menu[2],
            nav_down_button=self._menu[5],
            nav_left_button=self._menu[3],
            nav_right_button=self._menu[4],
            shift_button=self._menu[1],
            alt_button=self._menu[0],
        )
        #parameter_controls = self._dial_matrix)
        self.modhandler.legacy_shift_mode = AddLayerMode(
            self.modhandler,
            Layer(priority=6,
                  channel_buttons=self._matrix.submatrix[:, 1],
                  nav_matrix=self._matrix.submatrix[4:8, 2:6]))
        self.modhandler.shift_mode = AddLayerMode(
            self.modhandler,
            Layer(priority=6,
                  device_selector_matrix=self._matrix.submatrix[:, 0],
                  lock_button=self._livid,
                  key_buttons=self._matrix.submatrix[:, 7]))

        self.modhandler.set_enabled(False)
        self.modhandler.set_mod_button(self._livid)

    def _setup_modswitcher(self):
        self._modswitcher = ModesComponent(name='ModSwitcher')
        self._modswitcher.add_mode('mod', [
            self.modhandler, self._device,
            DelayMode(self.modhandler.update, delay=.5)
        ])
        self._modswitcher.add_mode('translations', [self._translations])
        self._modswitcher.selected_mode = 'translations'
        self._modswitcher.set_enabled(False)

    def _setup_modes(self):

        self._main_modes = ModesComponent(name='MainModes')
        self._main_modes.add_mode('disabled', [self._background])
        self._main_modes.add_mode('Mix', [
            self._session_modes, self._mixer, self._mixer.mix_layer,
            self._transport
        ])

        self._main_modes.add_mode(
            'DJ', [
                self._session_modes, self._mixer, self._mixer.dj_layer,
                self._dj_translation,
                tuple([self._assign_tempo, self._deassign_tempo])
            ],
            behaviour=DefaultedBehaviour(default_mode='Mix'))
        #tuple([ lambda:self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]]), self._set_tempo_buttons([])])],

        self._main_modes.add_mode(
            'Instrument', [
                self._update_keygroup_colors, self._bassgroup, self._keygroup,
                self._scale_mode, self._octave_offset_component, self._device,
                self._device_navigator, self._mixer,
                self._mixer.instrument_layer, self._drumgroup
            ],
            behaviour=DefaultedBehaviour(default_mode='Mix'))

        self._main_modes.add_mode(
            'Mod', [
                self._modswitcher, self._device, self._mixer,
                self._mixer.instrument_layer
            ],
            behaviour=DefaultedBehaviour(default_mode='Mix'))
        self._main_modes.layer = Layer(priority=5,
                                       Instrument_button=self._shift_l,
                                       DJ_button=self._shift_r,
                                       Mod_button=self._livid)
        self._main_modes.selected_mode = 'disabled'
        self._main_modes.set_enabled(True)

    def disconnect(self):
        super(OhmModes, self).disconnect()

    def strobe(self):
        if self._backlight_type != 'static':
            if self._backlight_type is 'pulse':
                self._backlight = int(
                    math.fabs(self._timer * 16 % 64 - 32) + 32)
            if self._backlight_type is 'up':
                self._backlight = int(self._timer * 8 % 64 + 16)
            if self._backlight_type is 'down':
                self._backlight = int(
                    math.fabs(int(self._timer * 8 % 64 - 64)) + 16)
        self._send_midi(tuple([176, 27, int(self._backlight)]))
        if self._ohm_type != 'static':
            if self._ohm_type is 'pulse':
                self._ohm = int(math.fabs(self._timer * 16 % 64 - 32) + 32)
            if self._ohm_type is 'up':
                self._ohm = int(self._timer * 8 % 64 + 16)
            if self._ohm_type is 'down':
                self._ohm = int(math.fabs(int(self._timer * 8 % 64 - 64)) + 16)
        self._send_midi(tuple([176, 63, int(self._ohm)]))
        self._send_midi(tuple([176, 31, int(self._ohm)]))

    def handle_sysex(self, midi_bytes):
        debug('sysex: ', str(midi_bytes))
        if len(midi_bytes) > 14:
            if midi_bytes[:6] == tuple([240, 0, 1, 97, 12, 64]):
                self._register_pad_pressed(midi_bytes[6:14])
            elif midi_bytes[:6] == tuple([240, 0, 1, 97, 17, 64]):
                self._register_pad_pressed(midi_bytes[6:14])
            elif midi_bytes[3:11] == tuple(
                [6, 2, 0, 1, 97, 1, 0] +
                [self._sysex_id]) or midi_bytes[3:11] == tuple(
                    [6, 2, 0, 1, 97, 1, 0] + [self._alt_sysex_id]):
                if not self._connected:
                    #self._connection_routine.kill()
                    self._connected = True
                    self._livid_settings.set_model(midi_bytes[11])
                    self._initialize_hardware()
                    self.schedule_message(1, self._initialize_script)

    @listens('device')
    def _on_device_changed(self):
        self.schedule_message(1, self._update_modswitcher)
        #debug('base on_device_changed')
        self._update_modswitcher()

    def _on_selected_track_changed(self):
        super(OhmModes, self)._on_selected_track_changed()
        if not len(self.song.view.selected_track.devices):
            self._update_modswitcher()

    def _update_modswitcher(self):
        debug('update modswitcher, mod is:', self.modhandler.active_mod())
        if self.modhandler.active_mod():
            self._modswitcher.selected_mode = 'mod'
        else:
            self._modswitcher.selected_mode = 'translations'

    @listens('selected_mode')
    def _on_scale_change(self, mode):
        debug('new scale is:', mode, self._scale_mode.selected_mode)
        self._keygroup.scale = SCALES.index(self._scale_mode.selected_mode)

    @listens('value')
    def _on_octave_change(self, value):
        self._keygroup.offset = value

    #stupid hack....4 hours wasted on two buttons is too long, so we're doing this instead
    def _update_keygroup_colors(self):
        self._grid[5][7].send_value(2, force=True)
        self._grid[6][7].send_value(2, force=True)

    #everything below needs to be consolidated into transport component
    def _assign_tempo(self):
        self._grid[5][7].send_value(4, True)
        self._grid[6][7].send_value(4, True)
        self._tempo_up_value.subject = self._grid[5][7]
        self._tempo_down_value.subject = self._grid[6][7]

    def _deassign_tempo(self):
        self._tempo_up_value.subject and self._tempo_up_value.subject.turn_off(
        )
        self._tempo_down_value.subject and self._tempo_down_value.subject.turn_off(
        )
        self._tempo_up_value.subject = None
        self._tempo_down_value.subject = None

    @listens('value')
    def _tempo_up_value(self, value):
        if value:
            self.song.tempo = round(min(self.song.tempo + 1, 999))

    @listens('value')
    def _tempo_down_value(self, value):
        if value:
            self.song.tempo = round(max(self.song.tempo - 1, 20))
class Minim(LividControlSurface):


	_sysex_id = 18
	_model_name = 'Minim'

	def __init__(self, c_instance, *a, **k):
		super(Minim, self).__init__(c_instance, *a, **k)
		self._shift_latching = LatchingShiftedBehaviour if SHIFT_LATCHING else ShiftedBehaviour
		self._skin = Skin(MinimColors)
		with self.component_guard():
			self._define_sysex()
			self._setup_monobridge()
			self._setup_controls()
			self._setup_background()
			self._setup_autoarm()
			self._setup_viewcontrol()
			self._setup_session()
			self._setup_mixer()
			self._setup_transport()
			self._setup_recorder()
			self._setup_instrument()
			self._setup_modes() 
			self._setup_m4l_interface()
		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Minim log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
		self.show_message('Minim Control Surface Loaded')
		self._background.set_enabled(True)
	

	def _check_connection(self):
		if not self._connected:
			debug(self._model_name, '_check_connection')
			self._livid_settings.new_query_surface()
			#self._connection_routine.restart()
			self.schedule_message(5, self._check_connection)
	

	def _initialize_hardware(self):
		debug('sending local control off')
		self.local_control_off.enter_mode()
	

	def _initialize_script(self):
		self._on_device_changed.subject = self._device_provider
		self._main_modes.set_enabled(True)
		self._main_modes.selected_mode = 'session'
		self._session_ring._update_highlight()
		self.refresh_state()
	

	def _setup_controls(self):
		is_momentary = True
		optimized = False
		resource = PrioritizedResource
		self._fader = MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = MINIM_SLIDER, name = 'Fader', script = self, mapping_feedback_delay = -1, optimized_send_midi = optimized, resource_type = resource)
		self._pad = [[MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = MINIM_PADS[row][column], name = 'Pad_' + str(column) + '_' + str(row), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource) for column in range(4)] for row in range(2)]
		self._button = [[MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = MINIM_BUTTONS[row][column], name = 'Button_' + str(column) + '_' + str(row), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource) for column in range(4)] for row in range(2)]
		self._side_button = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = MINIM_SIDE_BUTTONS[index], name = 'Side_Button_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource) for index in range(5)]		
		self._top_button = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = MINIM_TOP_BUTTONS[index], name = 'Top_Button_' + str(index), script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource) for index in range(2)]	
		self._bottom_button = MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = MINIM_BOTTOM_BUTTON, name = 'Bottom_Button', script = self, skin = self._skin, color_map = COLOR_MAP, optimized_send_midi = optimized, resource_type = resource)	


		self._matrix = ButtonMatrixElement(name = 'Pad_Matrix', rows = [self._button[:][0], self._pad[:][0], self._pad[:][1],self._button[:][1]])
		self._side_button_matrix = ButtonMatrixElement(name = 'Side_Button_Matrix', rows = [self._side_button])
		self._top_button_matrix = ButtonMatrixElement(name = 'Button_Matrix', rows = [self._top_button])
	

	def _setup_background(self):
		self._background = BackgroundComponent()
		self._background.layer = Layer(priority = 3, matrix = self._matrix.submatrix[:,:], side_buttons = self._side_button_matrix, top_buttons = self._top_button_matrix.submatrix[:,:], bottom_button = self._bottom_button)
		self._background.set_enabled(False)
	

	def _define_sysex(self):
		self._livid_settings = LividSettings(model = 18, control_surface = self)
		self.local_control_off = SendLividSysexMode(livid_settings = self._livid_settings, call = 'set_local_control', message = [42, 42])
	

	def _setup_autoarm(self):
		self._auto_arm = AutoArmComponent(name='Auto_Arm')
		self._auto_arm.can_auto_arm_track = self._can_auto_arm_track
		self._auto_arm._update_notification = lambda: None
	

	def _setup_viewcontrol(self):
		self._viewcontrol = ViewControlComponent()
		self._viewcontrol.layer = Layer(priority = 4, prev_track_button = self._top_button[0], next_track_button = self._top_button[1])
		self._viewcontrol.set_enabled(False)
	

	def _setup_transport(self):
		self._transport = TransportComponent(name = 'Transport') 
		self._transport.layer = Layer(priority = 4, play_button = self._side_button[0]) #, overdub_button = self._side_button[1])
		self._transport.set_enabled(False)
	

	def _setup_mixer(self):
		self._mixer = MonoMixerComponent(name = 'Mixer',tracks_provider = self._session_ring, track_assigner = simple_track_assigner, invert_mute_feedback = True, auto_name = True, enable_skinning = True)
		self._mixer._selected_strip.layer = Layer(priority = 4, volume_control = self._fader)
		self._mixer.solo_mute_record_stop_layer = AddLayerMode(self._mixer, Layer(priority = 4, 
																					mute_buttons = self._matrix.submatrix[:, 0], 
																					solo_buttons = self._matrix.submatrix[:, 1],
																					arm_buttons = self._matrix.submatrix[:, 2],
																					))
		self._mixer.select_layer = AddLayerMode(self._mixer, Layer(priority = 4, arming_track_select_buttons = self._matrix.submatrix[:, 3]))
		self._mixer.mute_layer = AddLayerMode(self._mixer, Layer(priority = 4, mute_buttons = self._matrix.submatrix[:, 3]))
	

	def _setup_session(self):
		self._session_ring = SessionRingComponent(name = 'Session_Ring', num_tracks = 4, num_scenes = 4)

		self._session = SessionComponent(name = 'Session', session_ring = self._session_ring, auto_name = True)
		self._session.cliplaunch_layer = AddLayerMode(self._session, Layer(priority = 4, clip_launch_buttons = self._matrix.submatrix[:,:]))
		self._session.stop_layer = AddLayerMode(self._session, Layer(priority = 4, stop_track_clip_buttons = self._matrix.submatrix[:,3]))

		self._session_navigation = SessionNavigationComponent(name = 'Session_Navigation', session_ring = self._session_ring)
		self._session_navigation._horizontal_layer = AddLayerMode(self._session_navigation, Layer(priority = 4, left_button = self._top_button[0], right_button = self._top_button[1]))
		self._session_navigation._vertical_layer = AddLayerMode(self._session_navigation, Layer(priority = 4, up_button = self._top_button[0], down_button = self._top_button[1]))
		self._session_navigation.set_enabled(False)
	

	def _setup_recorder(self):
		self._recorder = SessionRecordingComponent(view_controller = self._viewcontrol)
		self._recorder.layer = Layer(priority = 4, new_button = self._side_button[2], record_button = self._side_button[1])
		self._recorder.set_enabled(False)
	

	def _setup_instrument(self):
		self._grid_resolution = GridResolution()

		self._c_instance.playhead.enabled = True
		self._playhead_element = PlayheadElement(self._c_instance.playhead)

		self._drum_group_finder = PercussionInstrumentFinder(device_parent=self.song.view.selected_track)

		self._instrument = MinimMonoInstrumentComponent(name = 'InstrumentComponent', script = self, skin = self._skin, drum_group_finder = self._drum_group_finder, grid_resolution = self._grid_resolution, settings = DEFAULT_INSTRUMENT_SETTINGS, device_provider = self._device_provider, parent_task_group = self._task_group)
		self._instrument._drumpad._drumgroup._button_coordinates_to_pad_index = lambda first_note, coordinates: coordinates[1] + (abs(coordinates[0]-1)*4) + first_note
		self._instrument._drumpad._drumgroup.create_translation_entry = lambda button: (button.coordinate[1], button.coordinate[0]+2, button.identifier, button.channel)

		self._instrument.layer = Layer(priority = 6, shift_button = self._side_button[3])

		self._instrument.keypad_options_layer = AddLayerMode(self._instrument, Layer(priority = 6, 
									scale_up_button = self._button[0][3], 
									scale_down_button = self._button[0][2],
									offset_up_button = self._button[0][1], 
									offset_down_button = self._button[0][0],))
									#vertical_offset_up_button = self._top_button[1],
									#vertical_offset_down_button = self._top_button[0]))
		self._instrument.drumpad_options_layer = AddLayerMode(self._instrument, Layer(priority = 6, 
									scale_up_button = self._button[0][3],
									scale_down_button = self._button[0][2],
									drum_offset_up_button = self._button[0][1], 
									drum_offset_down_button = self._button[0][0],))

		self._instrument._keypad.main_layer = LayerMode(self._instrument._keypad, Layer(priority = 6, keypad_matrix = self._matrix.submatrix[:,1:3]))
		self._instrument._keypad.select_layer = LayerMode(self._instrument._keypad, Layer(priority = 6, keypad_select_matrix = self._matrix.submatrix[:, 1:3]))

		self._instrument._drumpad.main_layer = LayerMode(self._instrument._drumpad, Layer(priority = 6, drumpad_matrix = self._matrix.submatrix[:,1:3]))
		self._instrument._drumpad.select_layer = LayerMode(self._instrument._drumpad, Layer(priority = 6, drumpad_select_matrix = self._matrix.submatrix[:,1:3]))

		self._instrument._main_modes = ModesComponent(name = 'InstrumentModes')
		self._instrument._main_modes.add_mode('disabled', [])
		self._instrument._main_modes.add_mode('drumpad', [self._instrument._drumpad, self._instrument._drumpad.main_layer, self._instrument.drumpad_options_layer])
		self._instrument._main_modes.add_mode('drumpad_shifted', [self._instrument._drumpad, self._instrument._drumpad.select_layer, self._instrument.drumpad_options_layer])
		self._instrument._main_modes.add_mode('keypad', [self._instrument._keypad, self._instrument._keypad.main_layer, self._instrument.keypad_options_layer])
		self._instrument._main_modes.add_mode('keypad_shifted', [self._instrument._keypad, self._instrument._keypad.select_layer, self._instrument.keypad_options_layer])
		self._instrument.register_component(self._instrument._main_modes)

		self._instrument.set_enabled(False)
		#self._instrument.audioloop_layer = LayerMode(self._instrument, Layer(priority = 6, loop_selector_matrix = self._base_grid))
	

	def _setup_modes(self):
		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('disabled', [])
		self._main_modes.add_mode('session_shifted', [self._recorder, self._mixer, self._mixer.solo_mute_record_stop_layer, self._session, self._session.stop_layer, self._session_navigation, self._session_navigation._vertical_layer, self._transport], groups = ['shifted'], behaviour = self._shift_latching(color = 'Mode.Session'))
		self._main_modes.add_mode('session', [self._recorder, self._mixer, self._session, self._session.cliplaunch_layer, self._session_navigation, self._session_navigation._horizontal_layer, self._transport], behaviour = self._shift_latching(color = 'Mode.Session'))
		self._main_modes.add_mode('instrument_shifted', [self._recorder, self._mixer, self._mixer.mute_layer, self._viewcontrol, self._instrument, self._transport], groups = ['shifted'], behaviour = self._shift_latching(color = 'Mode.Instrument'))
		self._main_modes.add_mode('instrument', [self._recorder, self._mixer, self._mixer.select_layer, self._viewcontrol, self._instrument, self._transport], behaviour = self._shift_latching(color = 'Mode.Instrument'))

		self._main_modes.layer = Layer(priority = 6, session_button = self._side_button[4], instrument_button = self._side_button[3])
		self._main_modes.set_enabled(False)
		self._main_modes.selected_mode = 'disabled'
	

	def _can_auto_arm_track(self, track):
		routing = track.current_input_routing
		return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith('Livid Minim Input')
	

	def _setup_m4l_interface(self):
		self._m4l_interface = M4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard)
		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
	

	@listens('device')
	def _on_device_changed(self):
		pass
	

	def disconnect(self):
		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Minim log closed >>>>>>>>>>>>>>>>>>>>>>>>>')
		super(Minim, self).disconnect()
	

	def handle_sysex(self, midi_bytes):
		#debug('sysex: ', str(midi_bytes))
		#debug('matching:', midi_bytes[1:5], 'to', tuple([0, 1, 97]  + [self._sysex_id]))
		if len(midi_bytes)==9 and midi_bytes[1:5] == tuple([0, 1, 97]  + [self._sysex_id]):
			if not self._connected:
				#debug('connecting from sysex...')
				self._connected = True
				self._initialize_hardware()
				self._initialize_script()
Example #33
0
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'
Example #34
0
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'
Example #35
0
class Morph(ControlSurface):


	_model_name = 'Morph'

	def __init__(self, c_instance, *a, **k):
		self.log_message = logger.info
		super(Morph, self).__init__(c_instance, *a, **k)
		self._skin = Skin(MorphColors)
		with self.component_guard():
			self._setup_controls()
			self._setup_background()
			#self._setup_button_background()
			self._setup_drum_group()
			self._setup_keys_group()
			self._setup_piano_group()
			self._setup_autoarm()
			self._setup_device()
			self._setup_session()
			self._setup_session2()
			self._setup_mixer()
			self._setup_transport()
			self._setup_viewcontrol()
			self._setup_recorder()
			self._setup_translations()
			self._setup_modes()
		self._on_device_changed.subject = self._device_provider
		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Morph log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
		self.show_message('Morph Control Surface Loaded')
		self.schedule_message(2, self._init_surface)
		#debug('device:', self._device._get_device())



	def _init_surface(self):
		self._main_modes.selected_mode = 'Main'


	def _setup_controls(self):
		is_momentary = True
		optimized = False
		resource = ExclusiveResource #PrioritizedResource
		self._pad = [[ButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = MORPH_PADS[row][column], name = 'Pad_' + str(column) + '_' + str(row), skin = self._skin, resource_type = resource) for column in range(4)] for row in range(4)]
		for row in self._pad:
			for pad in row:
				pad.enabled = False
		self._button = [ButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = MORPH_BUTTONS[index], name = 'Button_' + str(index), skin = self._skin, resource_type = resource) for index in range(8)]
		for button in self._button:
			button.set_enabled = False
		self._key = [MorphButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = KEY_CHANNEL, identifier = MORPH_KEYS[index], name = 'Key_' + str(index), skin = self._skin, resource_type = resource) for index in range(13)]
		self._dials = [MorphEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = MORPH_DIALS[index], map_mode = Live.MidiMap.MapMode.absolute, name = 'Dial_' + str(index), resource_type = resource) for index in range(8)]
		self._slider = [MorphEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = MORPH_SLIDERS[index], map_mode = Live.MidiMap.MapMode.absolute, name = 'Slider_' + str(index), resource_type = resource) for index in range(2)]
		self._send_pressure = [MorphEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = MORPH_SEND_PRESSURE[index], map_mode = Live.MidiMap.MapMode.absolute, name = 'SendPressure_' + str(index), resource_type = resource) for index in range(2)]

		self._pad_matrix = ButtonMatrixElement(name = 'PadMatrix', rows = self._pad)
		self._dial_matrix = ButtonMatrixElement(name = 'DialMatrix', rows = [self._dials])
		self._button_matrix = ButtonMatrixElement(name = 'ButtonMatrix', rows = [self._button])
		self._key_matrix = ButtonMatrixElement(name = 'KeyMatrix', rows = [self._key])
		self._key_shift_matrix = ButtonMatrixElement(name = 'KeyShiftMatrix', rows = [self._key[2:11]])
		self._slider_matrix = ButtonMatrixElement(name = 'SliderMatrix', rows = [self._slider])
		self._send_pressure_matrix = ButtonMatrixElement(name = 'SendAMatrix', rows = [self._send_pressure])
		#self._shift_send_pressure_matrix = ButtonMatrixElement(name = 'ShiftSendMatrix', rows = [ [None, None, self._send_pressure[0], self._send_pressure[1]] ])

		self._piano_button = [MorphButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = PIANO_BUTTONS[index], name = 'PianoButton_' + str(index), skin = self._skin, resource_type = resource) for index in range(4)]
		for button in self._piano_button:
			button.enabled = False
		self._piano_key = [MorphButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = PIANO_CHANNEL, identifier = PIANO_KEYS[index], name = 'PianoKey_' + str(index), skin = self._skin, resource_type = resource) for index in range(25)]

		self._piano_matrix = ButtonMatrixElement(name = 'PianoMatrix', rows = [self._piano_key])
		self._piano_session_matrix = ButtonMatrixElement(name = 'PianoSessionMatrix', rows = [self._piano_key[0:4], self._piano_key[4:8], self._piano_key[8:12], self._piano_key[12:16]])


	def _setup_background(self):
		self._background = BackgroundComponent()
		self._background.layer = Layer(priority = 1, pads = self._pad_matrix, buttons = self._button_matrix, keys = self._key_matrix, dials = self._dial_matrix, sliders = self._slider_matrix)
		self._background.set_enabled(False)



	def _setup_drum_group(self):
		self._drum_group = MorphDrumGroup(set_pad_translations = self.set_pad_translations, translation_channel = DRUM_TRANSLATION_CHANNEL)
		self._drum_group.main_layer = AddLayerMode(self._drum_group, Layer(priority = 2, matrix = self._pad_matrix))
		self._drum_group.nav_layer = AddLayerMode(self._drum_group, Layer(priority = 2, scroll_up_button = self._key[1], scroll_down_button = self._key[0]))
		self._drum_group.set_enabled(False)


	def _setup_keys_group(self):
		self._keys_group = MorphKeysGroup()
		self._keys_group.main_layer = AddLayerMode(self._keys_group, Layer(priority = 2, matrix = self._key_matrix))
		self._keys_group.shift_layer = AddLayerMode(self._keys_group, Layer(priority = 2, matrix = self._key_shift_matrix, scroll_up_button = self._key[12], scroll_down_button = self._key[11]))
		self._keys_group.set_enabled(False)


	def _setup_piano_group(self):
		self._piano_group = MorphKeysGroup()
		self._piano_group._hi_limit = 8
		self._piano_group.main_layer = AddLayerMode(self._piano_group, Layer(priority = 2, matrix = self._piano_matrix, scroll_up_button = self._piano_button[1], scroll_down_button = self._piano_button[0]))
		#self._piano_group.shift_layer = AddLayerMode(self._piano_group, Layer(matrix = self._piano_shift_matrix, scroll_up_button = self._pian0[12], scroll_down_button = self._key[11]))
		self._piano_group.set_enabled(False)


	def _setup_autoarm(self):
		self._auto_arm = AutoArmComponent(name='Auto_Arm')
		self._auto_arm.can_auto_arm_track = self._can_auto_arm_track
		self._auto_arm._update_notification = lambda: None


	def _setup_transport(self):
		self._transport = TransportComponent(name = 'Transport')
		self._transport.layer = Layer(priority = 2, play_button = self._button[4], stop_button = self._button[5], overdub_button = self._button[6])
		self._transport.set_enabled(False)


	def _setup_translations(self):
		self._translations = TranslationComponent(name='Translations',
													channel=USER_CHANNEL,
													controls = self._dials + self._slider)
		self._translations.set_enabled(False)


	def _setup_device(self):
		self._device = MorphDeviceComponent(device_provider = self._device_provider, device_bank_registry = self._device_bank_registry)
		self._device.layer = Layer(priority = 2, parameter_controls = self._dial_matrix)
		self._device.set_enabled(False)


	def _setup_session(self):
		self._session_ring = SessionRingComponent(name = 'Session_Ring', num_tracks = 4, num_scenes = 4)

		self._session = SessionComponent(name = 'Session', session_ring = self._session_ring, auto_name = True)
		self._session.layer = Layer(priority = 2, clip_launch_buttons = self._pad_matrix,) # stop_all_clips_button = self._button[5])
		self._session.set_enabled(False)

		self._session_navigation = SessionNavigationComponent(name = 'Session_Navigation', session_ring = self._session_ring)
		self._session_navigation.layer = Layer(priority = 2, left_button = self._button[0], right_button = self._button[1])
		self._session_navigation.set_enabled(False)


	def _setup_session2(self):
		self._session2 = SessionComponent(name = 'Session2', session_ring = self._session_ring, auto_name = True)
		self._session2.layer = Layer(priority = 2, clip_launch_buttons = self._piano_session_matrix)
		self._session2.set_enabled(False)

		#self._session_navigation2 = SessionNavigationComponent(name = 'Session_Navigation2', session_ring = self._session_ring)
		#self._session_navigation2.layer = Layer(priority = 2, left_button = self._button[0], right_button = self._button[1])
		#self._session_navigation2.set_enabled(False)


	def _setup_mixer(self):
		self._mixer = MorphMixerComponent(tracks_provider = self._session_ring, track_assigner = SimpleTrackAssigner(), auto_name = True, invert_mute_feedback = False)
		self._mixer._selected_strip.main_layer = AddLayerMode(self._mixer._selected_strip, Layer(priority = 2, send_controls = self._send_pressure_matrix))
		self._mixer._selected_strip.shift_layer = AddLayerMode(self._mixer._selected_strip, Layer(priority = 2, stop_button = self._button[5]))
		#self._mixer._selected_strip.shift_layer = AddLayerMode(self._mixer, Layer(send_controls = self._shift_send_pressure_matrix.submatrix[:,]))


	def _setup_viewcontrol(self):
		self._viewcontrol = ViewControlComponent()
		self._viewcontrol.layer = Layer(priority = 2, prev_track_button = self._button[0], next_track_button = self._button[1])
		self._viewcontrol.set_enabled(False)


	def _setup_recorder(self):
		self._recorder = SessionRecordingComponent(view_controller = ViewControlComponent())
		self._recorder.layer = Layer(priority = 2, record_button = self._button[6])
		self._recorder.set_enabled(False)


	def _assign_crossfader(self):
		self._slider[1].connect_to(self.song.master_track.mixer_device.crossfader)
		debug('_assign_crossfader:', self._slider[1]._parameter_to_map_to)


	def _deassign_crossfader(self):
		self._slider[1].release_parameter()
		debug('_assign_crossfader:', self._slider[1]._parameter_to_map_to)


	def _setup_modes(self):
		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('disabled', self._background)
		self._main_modes.add_mode('Main', [self._piano_group, self._piano_group.main_layer, self._mixer, self._mixer._selected_strip.main_layer, self._viewcontrol, self._drum_group, self._drum_group.main_layer, self._keys_group, self._keys_group.main_layer, self._device, self._transport, self._assign_crossfader, self._report_mode])
		self._main_modes.add_mode('Shift', [self._mixer, self._mixer._selected_strip.shift_layer, self._session, self._session2, self._session_navigation,  self._drum_group, self._drum_group.nav_layer, self._keys_group, self._keys_group.shift_layer, self._deassign_crossfader, self._recorder, self._translations, self._report_mode], behaviour = MomentaryBehaviour())
		self._main_modes.layer = Layer(Shift_button = self._button[7])
		self._main_modes.set_enabled(True)
		self._report_mode.subject = self._main_modes
		self._main_modes.selected_mode = 'disabled'





	@listens('selected_mode')
	def _report_mode(self, *a, **k):
		debug('Mode:', self._main_modes.selected_mode)



	def _can_auto_arm_track(self, track):
		routing = track.current_input_routing
		return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith('Sensel') or routing.startswith('Morph')



	@listens('device')
	def _on_device_changed(self):
		debug('_on_device_changed:', self._device_provider.device)
		self._drum_group.set_drum_group_device(self._device_provider.device)



	def disconnect(self):
		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Morph log closed >>>>>>>>>>>>>>>>>>>>>>>>>')
		super(Morph, self).disconnect()


	def handle_sysex(self, midi_bytes):
		#debug('sysex: ', str(midi_bytes))
		#debug('matching:', midi_bytes[1:5], 'to', tuple([0, 1, 97]  + [self._sysex_id]))
		if len(midi_bytes)==9 and midi_bytes[1:5] == tuple([0, 1, 97]  + [self._sysex_id]):
			if not self._connected:
				#debug('connecting from sysex...')
				self._connected = True
				self._initialize_hardware()
				self._initialize_script()
Example #36
0
class MonoPedal(ControlSurface):


	def __init__(self, *a, **k):
		self.log_message = logger.warning
		super(MonoPedal, self).__init__(*a, **k)
		self._monomod_version = 'b996'
		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(is_momentary = True, msg_type = MIDI_CC_TYPE, channel = 0, identifier = PEDAL_DEFS[index], name = 'Pedal_'+str(index), script = self))
			self._pedal[index]._report = False
		self._pedal[7] = LoopPedalExpressionElement(script = self, msg_type = MIDI_CC_TYPE, channel = 0, identifier = 1, map_mode = 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, is_momentary = True, msg_type = MIDI_NOTE_TYPE, channel = 0, identifier = index+13, name = 'LED_' + str(index), script = 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 OhmModes(LividControlSurface):


	_sysex_id = 2
	_alt_sysex_id = 7
	_model_name = 'Ohm'
	_version_check = 'b996'
	_host_name = 'Ohm'

	def __init__(self, c_instance):
		super(OhmModes, self).__init__(c_instance)
		self._skin = Skin(OhmColors)
		with self.component_guard():
			self._define_sysex()
			self._setup_controls()
			self._setup_background()
			self._setup_m4l_interface()
			self._setup_translations()
			self._setup_session_control()
			self._setup_mixer_control()
			self._setup_device_control()
			self._setup_transport_control()
			self._setup_drumgroup()
			self._setup_keygroup()
			self._setup_bassgroup()
			self._setup_mod()
			self._setup_modswitcher()
			self._setup_modes()
		self._on_device_changed.subject = self._device_provider
	

	def _define_sysex(self):
		#self._send_midi(tuple(switchxfader))
		self._reverse_crossfader = SendLividSysexMode(self._livid_settings, call = 'reverse crossfader', message = [1])
	

	def update_display(self):
		super(OhmModes, self).update_display()
		#self.strobe()
	

	def _initialize_hardware(self):
		super(OhmModes, self)._initialize_hardware()
		#self._reverse_crossfader.enter_mode()
	

	def _initialize_script(self):
		super(OhmModes, self)._initialize_script()
		self._main_modes.selected_mode = 'Mix'
		self._session.update()
		self._mixer.update()
	

	def _setup_controls(self):
		is_momentary = True
		optimized = True
		resource = PrioritizedResource
		self._fader = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = OHM_FADERS[index], name = 'Fader_' + str(index), num = index, script = self, optimized_send_midi = optimized, resource_type = resource) for index in range(8)]
		self._button = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = OHM_BUTTONS[index], name = 'Button_' + str(index), script = self, skin = self._skin, optimized_send_midi = optimized, resource_type = resource) for index in range(8)]
		self._dial = [MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = OHM_DIALS[index], name = 'Encoder_' + str(index), num = index, script = self, optimized_send_midi = optimized, resource_type = resource) for index in range(16)]
		self._menu = [MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = OHM_MENU[index], name = 'Menu_' + str(index), script = self, skin = self._skin, optimized_send_midi = optimized, resource_type = resource) for index in range(6)]
		self._crossfader = MonoEncoderElement(msg_type = MIDI_CC_TYPE, channel = CHANNEL, identifier = CROSSFADER, name = 'Crossfader', script = self, optimized_send_midi = optimized, resource_type = resource)
		self._livid = MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = LIVID, name = 'Livid_Button', skin = self._skin, script = self, optimized_send_midi = optimized, resource_type = resource)
		self._shift_l = MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = SHIFT_L, name = 'Page_Button_Left', script = self, skin = self._skin, optimized_send_midi = optimized, resource_type = resource)
		self._shift_r = MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = SHIFT_R, name = 'Page_Button_Right', script = self, skin = self._skin, optimized_send_midi = optimized, resource_type = resource)
		self._grid = [[MonoButtonElement(is_momentary = is_momentary, msg_type = MIDI_NOTE_TYPE, channel = CHANNEL, identifier = column * 8 + row, name = 'Grid_' + str(column + (row*8)), script = self, skin = self._skin, optimized_send_midi = optimized, resource_type = resource) for column in range(8)] for row in range(8)]
		self._matrix = ButtonMatrixElement(name = 'Matrix', rows = [[self._grid[row][column] for column in range(8)] for row in range(8)])
		self._dial_matrix = ButtonMatrixElement(name = 'DialMatrix', rows = [self._dial[index*4:(index*4)+4] for index in range(4)])
		self._menu_matrix = ButtonMatrixElement(name = 'MenuMatrix', rows = [self._menu])
		self._fader_matrix = ButtonMatrixElement(name = 'FaderMatrix', rows = [self._fader])
		self._button_matrix = ButtonMatrixElement(name = 'ButtonMatrix', rows = [self._button])

		self._parameter_controls = ButtonMatrixElement(rows = [self._dial[:4], self._dial[4:8]])
	

	def _setup_background(self):
		self._background = BackgroundComponent(name = 'Background')
		self._background.layer = Layer(priority = 3, matrix = self._matrix.submatrix[:,:],
													livid_button = self._livid,
													shift_l_button = self._shift_l,
													shift_r_button = self._shift_r,
													crossfader = self._crossfader,
													dial_matrix = self._dial_matrix.submatrix[:,:],
													menu_matrix = self._menu_matrix.submatrix[:,:],
													fader_matrix = self._fader_matrix.submatrix[:,:],
													button_matrix = self._button_matrix.submatrix[:,:])
		self._background.set_enabled(False)
	

	def _setup_m4l_interface(self):
		self._m4l_interface = M4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard)
		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 _setup_translations(self):
		controls = []
		for array in self._grid:
			for button in array:
				controls.append(button)
		if FADER_BANKING:
			controls = controls + self._dial
		if DIAL_BANKING:
			controls = controls + self._dial
		self._translations = TranslationComponent(controls = controls, user_channel_offset = USER_CHANNEL, channel = 8)
		self._translations.layer = Layer(priority = 5, channel_selector_buttons = self._menu_matrix.submatrix[:,:])
		self._translations.set_enabled(False)

		dj_controls = [self._grid[7][index] for index in range(7)]
		self._dj_translation = TranslationComponent(controls = dj_controls, channel = 12)
	

	def _setup_session_control(self):
		self._session_ring = SessionRingComponent(num_tracks = 7, num_scenes = 5)
		self._session_ring.set_enabled(True)

		self._session_navigation = SessionNavigationComponent(session_ring = self._session_ring)
		self._session_navigation.scroll_navigation_layer = AddLayerMode(self._session_navigation, Layer(priority = 5, up_button = self._menu[2], down_button = self._menu[5], left_button = self._menu[3], right_button = self._menu[4]))
		self._session_navigation.page_navigation_layer = AddLayerMode(self._session_navigation, Layer(priority = 5, page_up_button = self._menu[2], page_down_button = self._menu[5], page_left_button = self._menu[3], page_right_button = self._menu[4]))
		self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._vertical_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation._horizontal_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
		self._session_navigation.set_enabled(False)

		self._session = OhmSessionComponent(name = 'Session', session_ring = self._session_ring, auto_name = True)
		hasattr(self._session, '_enable_skinning') and self._session._enable_skinning()
		self._session.set_enabled(False)
		self._session.clip_launch_layer = AddLayerMode(self._session, Layer(priority = 5,  clip_launch_buttons = self._matrix.submatrix[:7,:5]))
		self._session.scene_launch_layer = AddLayerMode(self._session, Layer(priority = 5,  scene_launch_buttons = self._matrix.submatrix[7,:5]))

		self._session_zoom = SessionOverviewComponent(name = 'Session_Overview', session_ring = self._session_ring, enable_skinning = True)
		self._session_zoom.layer = Layer(priority = 5, button_matrix = self._matrix.submatrix[:7,:5])
		self._session_zoom.set_enabled(False)

		self._session_modes = ModesComponent(name = 'Session_Modes')
		self._session_modes.add_mode('disabled', [self._session, 
														self._session.clip_launch_layer, 
														self._session.scene_launch_layer, 
														self._session_navigation, 
														self._session_navigation.scroll_navigation_layer])
		self._session_modes.add_mode('enabled', [self._session, 
														self._session.scene_launch_layer, 
														self._session_zoom, 
														self._session_navigation, 
														self._session_navigation.page_navigation_layer],  
														behaviour = DefaultedBehaviour())
		self._session_modes.layer = Layer(priority = 5, enabled_button = self._grid[7][7])
		self._session_modes.selected_mode = 'disabled'
		self._session_modes.set_enabled(False)
	

	def _setup_mixer_control(self):
		self._mixer = OhmMixerComponent(name = 'Mixer', tracks_provider = self._session_ring, track_assigner = simple_track_assigner, invert_mute_feedback = True, auto_name = True, enable_skinning = True)
		self._mixer.layer = Layer(priority = 5, volume_controls = self._fader_matrix.submatrix[:7, :], prehear_volume_control = self._dial[15], crossfader_control = self._crossfader)
		self._mixer.master_strip().layer = Layer(priority = 5, volume_control = self._fader[7], select_button = self._button[7])
		self._mixer.mix_layer = AddLayerMode(self._mixer, Layer(priority = 5, mute_buttons = self._matrix.submatrix[:7,5], 
													solo_buttons = self._matrix.submatrix[:7,6], 
													arm_buttons = self._matrix.submatrix[:7,7], 
													send_controls = self._dial_matrix.submatrix[:,:2],
													pan_controls = self._dial_matrix.submatrix[:7,2:],
													track_select_buttons = self._button_matrix.submatrix[:7,:],))
		self._mixer.dj_layer = AddLayerMode(self._mixer, Layer(priority = 5, mute_buttons = self._matrix.submatrix[:7,5],
													crossfade_toggles = self._matrix.submatrix[:7,6],
													end_pan_controls = self._dial_matrix.submatrix[:3,3],
													eq_gain_controls = self._dial_matrix.submatrix[:,:3],
													track_select_buttons = self._button_matrix.submatrix[:7,:],))
		self._mixer.instrument_layer = AddLayerMode(self._mixer, Layer(priority = 5, 
													instrument_send_controls = self._dial_matrix.submatrix[:,2:],
													arming_track_select_buttons = self._button_matrix.submatrix[:7,:]))
	

	def _setup_device_control(self):
		self._device = OhmDeviceComponent(script = self, name = 'Device_Component', device_provider = self._device_provider, device_bank_registry = DeviceBankRegistry())
		self._device.layer = Layer(priority = 5, parameter_controls = self._parameter_controls )
		self._device.set_enabled(False)

		self._device_navigator = DeviceNavigator(self._device_provider, self._mixer, self, name = 'Device_Navigator', )
		self._device_navigator.layer = Layer(priority = 5, prev_button = self._menu[3], next_button = self._menu[4])
		self._device_navigator.set_enabled(False)
	

	def _setup_transport_control(self):
		self._transport = OhmTransportComponent()
		self._transport.name = 'Transport'
		self._transport.layer = Layer(priority = 5, play_button = self._menu[0], stop_button = self._menu[1])
		self._transport.set_enabled(False)
	

	def _setup_drumgroup(self):
		self._drumgroup = MonoDrumGroupComponent(translation_channel = PAGE1_DRUM_CHANNEL, set_pad_translations = self.set_pad_translations)
		self._drumgroup._on_selected_track_changed.subject = None
		self._drumgroup.translation_channel = PAGE1_DRUM_CHANNEL
		self._drumgroup.layer = Layer(priority = 6, matrix = self._matrix.submatrix[:4, :4])
		self._drumgroup.set_enabled(False)
	

	def _setup_keygroup(self):
		self._scale_mode = ModesComponent(name = 'ScaleMode')
		for scale in SCALES:
			debug('making scale mode:', scale, str(scale))
			self._scale_mode.add_mode(str(scale), [])
		self._scale_mode.layer = Layer(priority = 5, 
										ionian_button = self._grid[7][0],
										dorian_button = self._grid[7][1],
										phrygian_button = self._grid[7][2],
										lydian_button = self._grid[7][3],
										mixolydian_button = self._grid[7][4],
										aeolian_button = self._grid[7][5],
										locrian_button = self._grid[7][6],
										major_button = self._grid[7][7])
		self._scale_mode.selected_mode = 'ionian'
		self._scale_mode.set_enabled(False)
		self._on_scale_change.subject = self._scale_mode

		self._octave_offset_component = ScrollingChannelizedSettingsComponent(name = 'NoteOffset', parent_task_group = self._task_group, value_dict = range(104), default_value_index = 36, default_channel = 0, bank_increment = 12, bank_on_color = 'MonoInstrument.OffsetOnValue', bank_off_color = 'MonoInstrument.OffsetOffValue')
		self._octave_offset_component.layer = Layer(priority = 5, bank_up_button = self._menu[2], bank_down_button = self._menu[5])
		self._on_octave_change.subject = self._octave_offset_component

		self._keygroup = OhmKeyGroupComponent()
		self._keygroup._on_selected_track_changed.subject = None
		self._keygroup.translation_channel = PAGE1_KEYS_CHANNEL
		self._keygroup.layer = Layer(priority = 6, matrix = self._matrix.submatrix[:, 4:7])
		self._keygroup.set_enabled(False)
	

	def _setup_bassgroup(self):
		self._bassgroup = OhmBassGroupComponent()
		self._bassgroup._on_selected_track_changed.subject = None
		self._bassgroup.translation_channel = PAGE1_BASS_CHANNEL
		self._bassgroup.layer = Layer(priority = 6, matrix = self._matrix.submatrix[4:, :4])
		self._bassgroup.set_enabled(False)
	

	def _setup_mod(self):
		self.monomodular = get_monomodular(self)
		self.monomodular.name = 'monomodular_switcher'
		self.modhandler = OhmModHandler(self)
		self.modhandler.name = 'ModHandler' 
		self.modhandler.layer = Layer(priority = 5, 
									grid = self._matrix.submatrix[:,:],
									nav_up_button = self._menu[2],
									nav_down_button = self._menu[5],
									nav_left_button = self._menu[3],
									nav_right_button =  self._menu[4],
									shift_button = self._menu[1],
									alt_button = self._menu[0],
									parameter_controls = self._dial_matrix)
		self.modhandler.legacy_shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6,
									channel_buttons = self._matrix.submatrix[:, 1],
									nav_matrix = self._matrix.submatrix[4:8, 2:6]))
		self.modhandler.shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6, 
									device_selector_matrix = self._matrix.submatrix[:, 0],
									lock_button = self._livid,
									key_buttons = self._matrix.submatrix[:, 7]))
									
		self.modhandler.set_enabled(False)
		self.modhandler.set_mod_button(self._livid)
	

	def _setup_modswitcher(self):
		self._modswitcher = ModesComponent(name = 'ModSwitcher')
		self._modswitcher.add_mode('mod', [self.modhandler, DelayMode(self.modhandler.update, delay = .5)])
		self._modswitcher.add_mode('translations', [self._translations])
		self._modswitcher.selected_mode = 'translations'
		self._modswitcher.set_enabled(False)
	

	def _setup_modes(self):

		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('disabled', [self._background])
		self._main_modes.add_mode('Mix', [self._session_modes, 
											self._mixer,
											self._mixer.mix_layer,
											self._transport])

		self._main_modes.add_mode('DJ', [self._session_modes,
											self._mixer,
											self._mixer.dj_layer,
											self._dj_translation,
											tuple([self._assign_tempo, self._deassign_tempo])],
											behaviour = DefaultedBehaviour(default_mode = 'Mix'))
											#tuple([ lambda:self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]]), self._set_tempo_buttons([])])],

		self._main_modes.add_mode('Instrument', [self._update_keygroup_colors,
											self._bassgroup,
											self._keygroup,
											self._scale_mode,
											self._octave_offset_component,
											self._device,
											self._device_navigator,
											self._mixer,
											self._mixer.instrument_layer,
											self._drumgroup],
											behaviour = DefaultedBehaviour(default_mode = 'Mix'))

		self._main_modes.add_mode('Mod', [self._modswitcher,
											self._device,
											self._mixer,
											self._mixer.instrument_layer], 
											behaviour = DefaultedBehaviour(default_mode = 'Mix'))
		self._main_modes.layer = Layer(priority = 5, Instrument_button = self._shift_l, DJ_button = self._shift_r, Mod_button = self._livid)
		self._main_modes.selected_mode = 'disabled'
		self._main_modes.set_enabled(True)
	

	def disconnect(self):
		super(OhmModes, self).disconnect()
	

	def strobe(self):
		if self._backlight_type != 'static':
			if self._backlight_type is 'pulse':
				self._backlight = int(math.fabs(self._timer * 16 % 64 - 32) + 32)
			if self._backlight_type is 'up':
				self._backlight = int(self._timer * 8 % 64 + 16)
			if self._backlight_type is 'down':
				self._backlight = int(math.fabs(int(self._timer * 8 % 64 - 64)) + 16)
		self._send_midi(tuple([176, 27, int(self._backlight)]))
		if self._ohm_type != 'static':
			if self._ohm_type is 'pulse':
				self._ohm = int(math.fabs(self._timer * 16 % 64 - 32) + 32)
			if self._ohm_type is 'up':
				self._ohm = int(self._timer * 8 % 64 + 16)
			if self._ohm_type is 'down':
				self._ohm = int(math.fabs(int(self._timer * 8 % 64 - 64)) + 16)
		self._send_midi(tuple([176, 63, int(self._ohm)]))
		self._send_midi(tuple([176, 31, int(self._ohm)]))
	

	def handle_sysex(self, midi_bytes):
		debug('sysex: ', str(midi_bytes))
		if len(midi_bytes) > 14:
			if midi_bytes[:6] == tuple([240, 0, 1, 97, 12, 64]):
				self._register_pad_pressed(midi_bytes[6:14])
			elif midi_bytes[:6] == tuple([240, 0, 1, 97, 17, 64]):
				self._register_pad_pressed(midi_bytes[6:14])
			elif midi_bytes[3:11] == tuple([6, 2, 0, 1, 97, 1, 0]  + [self._sysex_id]) or midi_bytes[3:11] == tuple([6, 2, 0, 1, 97, 1, 0]  + [self._alt_sysex_id]):
				if not self._connected:
					#self._connection_routine.kill()
					self._connected = True
					self._livid_settings.set_model(midi_bytes[11])
					self._initialize_hardware()
					self.schedule_message(1, self._initialize_script)
	

	@listens('device')
	def _on_device_changed(self):  
		self.schedule_message(1, self._update_modswitcher)
		#debug('base on_device_changed')
		self._update_modswitcher()
	

	def _on_selected_track_changed(self):
		super(OhmModes, self)._on_selected_track_changed()
		if not len(self.song.view.selected_track.devices):
			self._update_modswitcher()
	

	def _update_modswitcher(self):
		debug('update modswitcher, mod is:', self.modhandler.active_mod())
		if self.modhandler.active_mod():
			self._modswitcher.selected_mode = 'mod'
		else:
			self._modswitcher.selected_mode = 'translations'
	

	@listens('selected_mode')
	def _on_scale_change(self, mode):
		debug('new scale is:', mode, self._scale_mode.selected_mode)
		self._keygroup.scale = SCALES.index(self._scale_mode.selected_mode)
	

	@listens('value')
	def _on_octave_change(self, value):
		self._keygroup.offset = value
	

	#stupid hack....4 hours wasted on two buttons is too long, so we're doing this instead
	def _update_keygroup_colors(self):
		self._grid[5][7].send_value(2, force = True)
		self._grid[6][7].send_value(2, force = True)
	

	#everything below needs to be consolidated into transport component
	def _assign_tempo(self):
		self._grid[5][7].send_value(4, True)
		self._grid[6][7].send_value(4, True)
		self._tempo_up_value.subject = self._grid[5][7]
		self._tempo_down_value.subject = self._grid[6][7]
	

	def _deassign_tempo(self):
		self._tempo_up_value.subject and self._tempo_up_value.subject.turn_off()
		self._tempo_down_value.subject and self._tempo_down_value.subject.turn_off()
		self._tempo_up_value.subject = None
		self._tempo_down_value.subject = None
	

	@listens('value')
	def _tempo_up_value(self, value):
		if value:
			self.song.tempo = round(min(self.song.tempo + 1, 999))
	

	@listens('value')
	def _tempo_down_value(self, value):
		if value:
			self.song.tempo = round(max(self.song.tempo - 1, 20))
Example #38
0
class OhmModesRay(OhmModes):

    _sysex_id = 2
    _alt_sysex_id = 7
    _model_name = 'Ohm'
    _version_check = 'b996'
    _host_name = 'Ohm'
    device_provider_class = ModDeviceProvider

    def __init__(self, c_instance):
        super(OhmModes, self).__init__(c_instance)
        self._skin = Skin(OhmColors)
        with self.component_guard():
            self._define_sysex()
            self._setup_controls()
            self._setup_background()
            self._setup_m4l_interface()
            #self._setup_translations()
            self._setup_session_control()
            self._setup_mixer_control()
            #self._setup_device_control()
            #self._setup_transport_control()
            #self._setup_drumgroup()
            #self._setup_keygroup()
            #self._setup_bassgroup()
            #self._setup_mod()
            #self._setup_modswitcher()
            self._setup_modes()
        #self._on_device_changed.subject = self._device_provider

    def _setup_session_control(self):
        self._session_ring = SessionRingComponent(num_tracks=7, num_scenes=7)
        self._session_ring.set_enabled(True)

        self._session_navigation = SessionNavigationComponent(
            session_ring=self._session_ring)
        self._session_navigation.scroll_navigation_layer = AddLayerMode(
            self._session_navigation,
            Layer(priority=5,
                  up_button=self._menu[1],
                  down_button=self._menu[4],
                  left_button=self._menu[3],
                  right_button=self._menu[5]))
        self._session_navigation.page_navigation_layer = AddLayerMode(
            self._session_navigation,
            Layer(priority=5,
                  page_up_button=self._menu[2],
                  page_down_button=self._menu[5],
                  page_left_button=self._menu[3],
                  page_right_button=self._menu[4]))
        self._session_navigation._vertical_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._vertical_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._horizontal_banking.scroll_up_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._horizontal_banking.scroll_down_button.color = 'Session.NavigationButtonOn'
        self._session_navigation._vertical_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
        self._session_navigation._vertical_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
        self._session_navigation._horizontal_paginator.scroll_up_button.color = 'Session.PageNavigationButtonOn'
        self._session_navigation._horizontal_paginator.scroll_down_button.color = 'Session.PageNavigationButtonOn'
        self._session_navigation.set_enabled(False)

        self._session = SpecialOhmSessionComponent(
            name='Session', session_ring=self._session_ring, auto_name=True)
        self._session.set_enabled(False)
        self._session.clip_launch_layer = AddLayerMode(
            self._session,
            Layer(priority=5,
                  clip_launch_buttons=self._matrix.submatrix[:7, :7]))
        self._session.scene_launch_layer = AddLayerMode(
            self._session,
            Layer(priority=5,
                  scene_launch_buttons=self._matrix.submatrix[7, :7]))
        self._session.stop_clips_layer = AddLayerMode(
            self._session,
            Layer(priority=5,
                  stop_track_clip_buttons=self._matrix.submatrix[:7, 7],
                  stop_all_clips_button=self._grid[7][7]))
        """self._session_zoom = SessionOverviewComponent(name = 'Session_Overview', session_ring = self._session_ring, enable_skinning = True)
		self._session_zoom.layer = Layer(priority = 5, button_matrix = self._matrix.submatrix[:7,:7])
		self._session_zoom.set_enabled(False)

		self._session_modes = ModesComponent(name = 'Session_Modes')
		self._session_modes.add_mode('disabled', [self._session, 
														self._session.clip_launch_layer, 
														self._session.scene_launch_layer, 
														self._session_navigation, 
														self._session_navigation.scroll_navigation_layer])
		self._session_modes.add_mode('enabled', [self._session, 
														self._session.scene_launch_layer, 
														self._session_zoom, 
														self._session_navigation, 
														self._session_navigation.page_navigation_layer],  
														behaviour = DefaultedBehaviour())
		self._session_modes.layer = Layer(priority = 5, enabled_button = self._grid[7][7])
		self._session_modes.selected_mode = 'disabled'
		self._session_modes.set_enabled(False)"""

    def _setup_mixer_control(self):
        self._mixer = OhmMixerComponent(name='Mixer',
                                        tracks_provider=self._session_ring,
                                        track_assigner=simple_track_assigner,
                                        invert_mute_feedback=True,
                                        auto_name=True,
                                        enable_skinning=True)
        #self._mixer.layer = Layer(priority = 5, volume_controls = self._fader_matrix.submatrix[:7, :], prehear_volume_control = self._dial[15], crossfader_control = self._crossfader)
        self._mixer.layer = Layer(
            priority=5, solo_buttons=self._button_matrix.submatrix[:7, :])
        """self._mixer.master_strip().layer = Layer(priority = 5, volume_control = self._fader[7], select_button = self._button[7])
		self._mixer.mix_layer = AddLayerMode(self._mixer, Layer(priority = 5, mute_buttons = self._matrix.submatrix[:7,5], 
													solo_buttons = self._matrix.submatrix[:7,6], 
													arm_buttons = self._matrix.submatrix[:7,7], 
													send_controls = self._dial_matrix.submatrix[:,:2],
													pan_controls = self._dial_matrix.submatrix[:7,2:],
													track_select_buttons = self._button_matrix.submatrix[:7,:],))
		self._mixer.dj_layer = AddLayerMode(self._mixer, Layer(priority = 5, mute_buttons = self._matrix.submatrix[:7,5],
													crossfade_toggles = self._matrix.submatrix[:7,6],
													end_pan_controls = self._dial_matrix.submatrix[:3,3],
													eq_gain_controls = self._dial_matrix.submatrix[:,:3],
													track_select_buttons = self._button_matrix.submatrix[:7,:],))
		self._mixer.instrument_layer = AddLayerMode(self._mixer, Layer(priority = 5, 
													instrument_send_controls = self._dial_matrix.submatrix[:,2:],
													arming_track_select_buttons = self._button_matrix.submatrix[:7,:]))
		"""

    def _setup_modes(self):

        self._main_modes = ModesComponent(name='MainModes')
        self._main_modes.add_mode('disabled', [self._background])
        self._main_modes.add_mode('Mix', [
            self._mixer, self._session, self._session.stop_clips_layer,
            self._session.clip_launch_layer, self._session.scene_launch_layer,
            self._session_navigation,
            self._session_navigation.scroll_navigation_layer
        ])

        self._main_modes.selected_mode = 'disabled'
        self._main_modes.set_enabled(True)