コード例 #1
0
 def _create_session_mode(self):
     session_modes = ModesComponent(is_enabled=False)
     session_modes.add_mode('session', self._session_mode)
     session_modes.add_mode('overview', self._session_overview_mode)
     session_modes.layer = Layer(cycle_mode_button='layout_button')
     session_modes.selected_mode = 'session'
     return [session_modes, self._session_navigation]
コード例 #2
0
ファイル: push2.py プロジェクト: aumhaa/livepy_diff
 def _create_clip_mode(self):
     base_loop_layer = Layer(shift_button='shift_button', loop_button='track_state_buttons_raw[1]')
     self._loop_controller = LoopSettingsControllerComponent(is_enabled=False)
     self._model.loopSettingsView = self._loop_controller
     audio_clip_layer = Layer(warp_mode_encoder='parameter_controls_raw[5]', transpose_encoder='parameter_controls_raw[6]', detune_encoder=self._with_shift('parameter_controls_raw[6]'), gain_encoder='parameter_controls_raw[7]', shift_button='shift_button')
     audio_clip_controller = AudioClipSettingsControllerComponent(is_enabled=False)
     self._model.audioClipSettingsView = audio_clip_controller
     clip_control_mode_selector = ModesComponent(is_enabled=False)
     clip_control_mode_selector.add_mode('midi', [make_freeze_aware(self._loop_controller, base_loop_layer + Layer(encoders=self.elements.global_param_controls.submatrix[:3, :]))])
     clip_control_mode_selector.add_mode('audio', [make_freeze_aware(self._loop_controller, base_loop_layer + Layer(encoders=self.elements.global_param_controls.submatrix[1:4, :], zoom_encoder='fine_grain_param_controls_raw[0]')), make_freeze_aware(audio_clip_controller, audio_clip_layer)])
     clip_control_mode_selector.add_mode('no_clip', [])
     clip_control_mode_selector.selected_mode = 'no_clip'
     clip_control = ClipControlComponent(loop_controller=self._loop_controller, audio_clip_controller=audio_clip_controller, mode_selector=clip_control_mode_selector, decorator_factory=self._clip_decorator_factory, is_enabled=False)
     self._model.clipView = clip_control
     return [partial(self._view_control.show_view, 'Detail/Clip'), clip_control_mode_selector, clip_control]
コード例 #3
0
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()
コード例 #4
0
ファイル: MonoPedal.py プロジェクト: amuntner/m4m7
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)
コード例 #5
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 = 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()
コード例 #6
0
 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
コード例 #7
0
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.__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=u'scene_launch_buttons')

    def _create_stop_solo_mute_modes(self):
        self._stop_solo_mute_modes = ModesComponent(
            name=u'Stop_Solo_Mute_Modes',
            is_enabled=False,
            support_momentary_mode_cycling=False,
            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(
            u'launch', None, cycle_mode_button_color=u'Mode.Launch.On')
        self._stop_solo_mute_modes.add_mode(
            u'stop',
            AddLayerMode(self._session,
                         Layer(stop_track_clip_buttons=bottom_row)),
            cycle_mode_button_color=u'Session.StopClip')
        self._stop_solo_mute_modes.add_mode(
            u'solo',
            AddLayerMode(self._mixer, Layer(solo_buttons=bottom_row)),
            cycle_mode_button_color=u'Mixer.SoloOn')
        self._stop_solo_mute_modes.add_mode(
            u'mute',
            AddLayerMode(self._mixer, Layer(mute_buttons=bottom_row)),
            cycle_mode_button_color=u'Mixer.MuteOff')
        self._stop_solo_mute_modes.selected_mode = u'launch'
        self._stop_solo_mute_modes.set_enabled(True)

    def _create_session_modes(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'))
        self._session_modes = SessionModesComponent(
            name=u'Session_Modes',
            is_enabled=False,
            layer=Layer(
                cycle_mode_button=u'session_mode_button',
                mode_button_color_control=u'session_button_color_element'))
        self._session_modes.add_mode(u'launch', None)
        (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')),
             AddLayerMode(
                 self._background,
                 Layer(scene_launch_buttons=u'scene_launch_buttons')))), )
        self._session_modes.selected_mode = u'launch'
        self._session_modes.set_enabled(True)
        self.__on_session_mode_changed.subject = self._session_modes

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

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

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

    @listens(u'value')
    def __on_layout_switch_value(self, value):
        self._last_layout_byte = value
コード例 #8
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,
                device_selector_matrix=self.elements.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 _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_device_component(self):
        device_component_layer = Layer(
            parameter_touch_buttons=ButtonMatrixElement(
                rows=[self.elements.global_param_touch_buttons_raw]),
            shift_button=u'shift_button')
        return DeviceComponentProvider(
            device_component_layer=device_component_layer,
            device_decorator_factory=self._device_decorator_factory,
            device_bank_registry=self._device_bank_registry,
            banking_info=self._banking_info,
            name=u'DeviceComponent',
            is_enabled=False,
            delete_button=self.elements.delete_button)

    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)
        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._tagged_defaults = TaggedDefaultsComponent(self)
        self._tagged_defaults.layer = Layer(priority=9,
                                            reset_button='side_buttons_raw[7]')
        self._tagged_defaults.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._tagged_defaults)

        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,
                    ButtonElement) 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')
コード例 #9
0
class KeyLabEssential(ControlSurface):
    mixer_component_type = MixerComponent
    session_component_type = SessionComponent
    view_control_component_type = ViewControlComponent
    hardware_settings_component_type = HardwareSettingsComponent
    channel_strip_component_type = ChannelStripComponent

    def __init__(self, *a, **k):
        super(KeyLabEssential, self).__init__(*a, **k)
        with self.component_guard():
            with inject(skin=const(default_skin)).everywhere():
                self._create_controls()
            self._create_hardware_settings()
        self._on_focused_view_changed.subject = self.application.view
        self._hardware_settings.set_hardware_live_mode_enabled(True)
        self._on_memory_preset_changed_on_hardware.subject = self._hardware_settings
        self._hardware_settings.select_memory_preset(
            sysex.DAW_MEMORY_PRESET_INDEX)
        with self.component_guard():
            self._create_transport()
            self._create_undo()
            self._create_session()
            self._create_navigation()
            self._create_mixer()
            self._create_view_control()
            self._create_arrangement()
            self._create_jogwheel_modes()

    def port_settings_changed(self):
        super(KeyLabEssential, self).port_settings_changed()
        self._hardware_settings.set_hardware_live_mode_enabled(True)

    def _create_controls(self):
        self._hardware_live_mode_switch = SysexElement(
            send_message_generator=lambda b: sysex.LIVE_MODE_MESSAGE_HEADER +
            (b, sysex.END_BYTE),
            default_value=sysex.OFF_VALUE,
            name=u'Hardware_Live_Mode_Switch')
        self._memory_preset_switch = SysexElement(
            send_message_generator=lambda b: sysex.
            MEMORY_PRESET_SWITCH_MESSAGE_HEADER + (b, sysex.END_BYTE),
            sysex_identifier=sysex.MEMORY_PRESET_SWITCH_MESSAGE_HEADER,
            name=u'Memory_Preset_Switch')
        self._memory_preset_select_mode_switch = SysexElement(
            sysex_identifier=sysex.MEMORY_PRESET_SELECT_MODE_MESSAGE_HEADER,
            name=u'Memory_Preset_Select_Mode')
        self._play_button = create_button(94, u'Play_Button')
        self._stop_button = create_button(93, u'Stop_Button')
        self._punch_in_button = create_button(87, u'Punch_In_Button')
        self._punch_out_button = create_button(88, u'Punch_Out_Button')
        self._metronome_button = create_button(89, u'Metronome_Button')
        self._loop_button = create_button(86, u'Loop_Button')
        self._rwd_button = create_button(91, u'Rewind_Button')
        self._ff_button = create_button(92, u'Fast_Forward_Button')
        self._record_button = create_button(95, u'Record_Button')
        self._undo_button = create_button(81, u'Undo_Button')
        self._bank_left_button = create_button(46, u'Bank_Left_Button')
        self._bank_right_button = create_button(47, u'Bank_Right_Button')
        self._left_button = create_button(48, u'Left_Button')
        self._right_button = create_button(49, u'Right_Button')
        self._left_arrow_button = create_button(98, u'Left_Arrow_Button')
        self._right_arrow_button = create_button(99, u'Right_Arrow_Button')
        self._marker_button = create_button(84, u'Marker_Button')
        self._pads = ButtonMatrixElement(rows=[[
            create_button(col + 36, u'Pad_%d' % (col, ), channel=10)
            for col in range(8)
        ]],
                                         name=u'Pad_Matrix')
        self._pad_leds = ButtonMatrixElement(rows=[[
            create_pad_led(column + 112, u'Pad_LED_%d' % (column, ))
            for column in range(8)
        ]],
                                             name=u'Pad_LED_Matrix')
        self._faders = ButtonMatrixElement(rows=[[
            SliderElement(msg_type=MIDI_PB_TYPE,
                          channel=index,
                          identifier=None,
                          name=u'Fader_%d' % (index, )) for index in range(8)
        ]],
                                           name=u'Faders')
        self._master_fader = SliderElement(MIDI_PB_TYPE,
                                           8,
                                           identifier=None,
                                           name=u'Master_Fader')
        self._encoders = ButtonMatrixElement(rows=[[
            create_ringed_encoder(index + 16, index +
                                  48, u'Device_Encoder_%d' % (index, ))
            for index in range(8)
        ]])
        self._jogwheel = EncoderElement(
            MIDI_CC_TYPE,
            0,
            60,
            Live.MidiMap.MapMode.relative_smooth_signed_bit,
            name=u'Jogwheel')

    def _create_hardware_settings(self):
        self._hardware_settings = self.hardware_settings_component_type(
            is_enabled=False,
            layer=Layer(
                hardware_live_mode_switch=self._hardware_live_mode_switch,
                memory_preset_switch=self._memory_preset_switch,
                memory_preset_select_mode_switch=self.
                _memory_preset_select_mode_switch),
            name=u'Hardware_Settings')
        self._hardware_settings.set_enabled(True)

    def _create_transport(self):
        self._transport = TransportComponent(
            is_enabled=False,
            layer=Layer(play_button=self._play_button,
                        stop_button=self._stop_button,
                        punch_in_button=self._punch_in_button,
                        punch_out_button=self._punch_out_button,
                        loop_button=self._loop_button,
                        metronome_button=self._metronome_button,
                        record_button=self._record_button))
        self._transport.set_seek_buttons(self._ff_button, self._rwd_button)
        self._transport.set_enabled(True)

    def _create_undo(self):
        self._undo = UndoComponent(is_enabled=False,
                                   layer=Layer(undo_button=self._undo_button))
        self._undo.set_enabled(True)

    def _create_session(self):
        self._session_ring = SessionRingComponent(
            num_tracks=self._pads.width(),
            num_scenes=self._pads.height(),
            name=u'Session_Ring')
        self._session_ring.set_enabled(False)
        self._session = self.session_component_type(
            session_ring=self._session_ring,
            name=u'Session',
            is_enabled=False,
            layer=Layer(clip_launch_buttons=self._pads,
                        clip_slot_leds=self._pad_leds))
        self._session.set_enabled(True)

    def _create_navigation(self):
        self._session_navigation = SessionNavigationComponent(
            session_ring=self._session_ring,
            is_enabled=False,
            layer=Layer(page_left_button=self._bank_left_button,
                        page_right_button=self._bank_right_button,
                        left_button=self._left_button,
                        right_button=self._right_button),
            name=u'Session_Navigation')
        self._session_navigation.set_enabled(True)

    def _create_mixer(self):
        # self._mixer = self.mixer_component_type(tracks_provider=self._session_ring, channel_strip_component_type=self.channel_strip_component_type, is_enabled=False, layer=Layer(volume_controls=self._faders, pan_controls=self._encoders))
        self._mixer = self.mixer_component_type(
            tracks_provider=self._session_ring,
            channel_strip_component_type=self.channel_strip_component_type,
            is_enabled=False,
            layer=Layer(volume_controls=self._faders))
        self._mixer.master_strip().set_volume_control(self._master_fader)
        self._mixer.set_enabled(True)

    def _create_view_control(self):
        self._view_control = self.view_control_component_type(
            is_enabled=False,
            layer=Layer(prev_track_button=self._left_arrow_button,
                        next_track_button=self._right_arrow_button,
                        scene_scroll_encoder=self._jogwheel),
            name=u'View_Control')
        self._view_control.set_enabled(True)

    def _create_arrangement(self):
        self._arrangement = ArrangementComponent(
            is_enabled=False,
            layer=Layer(set_or_delete_cue_button=self._marker_button),
            name=u'Arrangement')
        self._arrangement.set_enabled(True)

    def _create_jogwheel_modes(self):
        self._jogwheel_modes = ModesComponent()
        self._jogwheel_modes.add_mode(
            u'Session',
            AddLayerMode(self._view_control,
                         Layer(scene_scroll_encoder=self._jogwheel)))
        self._jogwheel_modes.add_mode(
            u'Arranger',
            AddLayerMode(self._arrangement,
                         Layer(jump_encoder=self._jogwheel)))
        self._on_focused_view_changed()

    @listens(u'focused_document_view')
    def _on_focused_view_changed(self):
        view = self.application.view.focused_document_view
        if self._jogwheel_modes:
            self._jogwheel_modes.selected_mode = view

    @listens(u'daw_preset')
    def _on_memory_preset_changed_on_hardware(self, is_daw_preset_on):
        self._session.set_allow_update(is_daw_preset_on)
        if is_daw_preset_on:
            for control in self.controls:
                control.clear_send_cache()

        self._session.set_enabled(is_daw_preset_on)
コード例 #10
0
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 == '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)
        self._create_quantization()
        with inject(fixed_length_recording=(const(
                self._fixed_length_recording)),
                    quantization_component=(const(
                        self._quantization))).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_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._Launchpad_Pro_MK3__on_layout_switch_value.subject = self._elements.layout_switch

    def _create_session_overview(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'))

    def _create_auto_arm(self):
        self._auto_arm = AutoArmComponent(name='Auto_Arm', is_enabled=False)

    def _create_background(self):
        self._background = BackgroundComponent(
            name='Background',
            is_enabled=False,
            add_nop_listeners=True,
            layer=(Layer(
                clear_button='clear_button',
                duplicate_button='duplicate_button',
                quantize_button='quantize_button',
                scene_launch_buttons='scene_launch_buttons',
                priority=(-1)
            ) + Layer(
                duplicate_button_with_shift='duplicate_button_with_shift',
                track_select_buttons_with_shift=
                'track_select_buttons_with_shift',
                up_button_with_shift='up_button_with_shift',
                down_button_with_shift='down_button_with_shift',
                left_button_with_shift='left_button_with_shift',
                right_button_with_shift='right_button_with_shift',
                double_button='duplicate_button_with_shift',
                clear_button_with_shift='clear_button_with_shift',
                volume_button_with_shift='volume_button_with_shift',
                pan_button_with_shift='pan_button_with_shift',
                sends_button_with_shift='sends_button_with_shift',
                device_button_with_shift='device_button_with_shift',
                stop_clip_button_with_shift='stop_clip_button_with_shift',
                fixed_length_button_with_shift='fixed_length_button_with_shift'
            )))
        self._background.set_enabled(True)

    def _create_print_to_clip(self):
        self._print_to_clip = PrintToClipComponent(
            name='Print_To_Clip',
            is_enabled=False,
            layer=Layer(print_to_clip_control='print_to_clip_element',
                        print_to_clip_enabler='print_to_clip_enabler_element'))
        self._print_to_clip.set_enabled(True)

    def _create_undo_redo(self):
        self._undo_redo = UndoRedoComponent(
            name='Undo_Redo',
            is_enabled=False,
            layer=Layer(undo_button='record_arm_button_with_shift',
                        redo_button='mute_button_with_shift'))
        self._undo_redo.undo_button.color = 'Action.Undo'
        self._undo_redo.undo_button.pressed_color = 'Action.UndoPressed'
        self._undo_redo.redo_button.color = 'Action.Redo'
        self._undo_redo.redo_button.pressed_color = 'Action.RedoPressed'
        self._undo_redo.set_enabled(True)

    def _create_transport(self):
        self._transport = TransportComponent(
            name='Transport',
            is_enabled=False,
            layer=Layer(play_button='play_button',
                        continue_playing_button='play_button_with_shift',
                        metronome_button='solo_button_with_shift',
                        capture_midi_button='record_button_with_shift',
                        tap_tempo_button='sends_button_with_shift'))
        self._transport.tap_tempo_button.color = 'Transport.TapTempo'
        self._transport.set_enabled(True)

    def _create_clip_actions(self):
        self._clip_actions = ClipActionsComponent(
            name='Clip_Actions',
            quantization_component=(self._quantization),
            is_enabled=False,
            layer=Layer(duplicate_button='duplicate_button',
                        quantize_button='quantize_button',
                        double_loop_button='duplicate_button_with_shift'))

    def _create_quantization(self):
        self._quantization = QuantizationComponent(
            name='Quantization',
            is_enabled=False,
            layer=Layer(
                quantization_toggle_button='quantize_button_with_shift'))
        self._quantization.set_enabled(True)

    def _create_fixed_length(self):
        self._fixed_length = FixedLengthComponent(
            fixed_length_setting=(self._fixed_length_setting),
            name='Fixed_Length',
            is_enabled=False,
            layer=Layer(fixed_length_button='fixed_length_button'))
        self._fixed_length.settings_component.layer = Layer(
            length_option_buttons='track_select_buttons')
        self._fixed_length.set_enabled(True)

    def _create_drum_group(self):
        self._drum_group = DrumGroupComponent(
            (self._clip_actions),
            name='Drum_Group',
            is_enabled=False,
            translation_channel=DRUM_FEEDBACK_CHANNEL,
            layer=Layer(matrix='drum_pads'))
        self._drum_group.set_enabled(True)

    def _create_device_parameters(self):
        self._device_parameters = SimpleDeviceParameterComponent(
            name='Device_Parameters',
            is_enabled=False,
            device_bank_registry=(self._device_bank_registry),
            layer=Layer(
                parameter_controls='device_button_faders',
                static_color_controls='device_button_fader_color_elements',
                stop_fader_control='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='Device_Navigation')

    def _create_scale_pad_translator(self):
        self._scale_pad_translator = ConfigurablePlayableComponent(
            SCALE_FEEDBACK_CHANNEL,
            name='Scale_Pads',
            is_enabled=False,
            layer=Layer(matrix='scale_pads'))
        self._scale_pad_translator.set_enabled(True)

    def _create_mixer_modes(self):
        self._mixer_modes = ModesComponent(name='Mixer_Modes',
                                           is_enabled=False,
                                           enable_skinning=True,
                                           layer=Layer(
                                               arm_button='record_arm_button',
                                               mute_button='mute_button',
                                               solo_button='solo_button',
                                               volume_button='volume_button',
                                               pan_button='pan_button',
                                               sends_button='sends_button',
                                               device_button='device_button',
                                               stop_button='stop_clip_button'))
        self._mixer.layer = Layer(volume_controls='volume_button_faders',
                                  pan_controls='pan_button_faders',
                                  send_controls='sends_button_faders')
        reselect_track_select_mode = partial(setattr, self._mixer_modes,
                                             'selected_mode', 'track_select')

        def restore_main_layout():
            if self._can_restore_layout:
                if 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 '{}_buttons'.format(name)
            control_dict = {control_key: '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('track_select')
        add_track_select_button_mode('arm')
        add_track_select_button_mode('mute')
        add_track_select_button_mode('solo')
        add_track_select_button_mode('stop',
                                     control='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='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(
            'volume',
            0, (AddLayerMode(
                self._mixer,
                Layer(
                    static_color_controls='volume_button_fader_color_elements')
            )),
            static_color=(Rgb.GREEN.midi_value))
        add_fader_mode(
            'pan', 1,
            AddLayerMode(
                self._mixer,
                Layer(track_color_controls='pan_button_fader_color_elements')))
        add_fader_mode(
            'sends', 2,
            AddLayerMode(
                self._mixer,
                Layer(send_select_buttons='scene_launch_buttons',
                      return_track_color_controls=
                      'sends_button_fader_color_elements',
                      stop_fader_control='stop_fader_element')))
        add_fader_mode(
            'device', 3,
            (AddLayerMode(
                self._background,
                Layer(up_button='up_button', down_button='down_button')),
             AddLayerMode(
                 self._device_navigation,
                 Layer(prev_button='left_button', next_button='right_button')),
             AddLayerMode(self._device_parameters,
                          Layer(bank_select_buttons='scene_launch_buttons'))))
        self._mixer_modes.selected_mode = 'track_select'
        self._mixer_modes.set_enabled(True)

    def _create_session_modes(self):
        self._session_modes = ModesComponent(
            name='Session_Modes',
            is_enabled=False,
            layer=Layer(overview_button='session_mode_button'))
        self._session_modes.add_mode(
            'launch',
            AddLayerMode(
                self._session,
                Layer(managed_select_button='shift_button',
                      managed_delete_button='clear_button',
                      managed_duplicate_button='duplicate_button',
                      managed_quantize_button='quantize_button',
                      managed_double_button='duplicate_button_with_shift',
                      scene_launch_buttons='scene_launch_buttons')))
        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'))),
            behaviour=(MomentaryBehaviour()))
        self._session_modes.selected_mode = 'launch'

    def _create_note_modes(self):
        self._note_modes = ModesComponent(name='Note_Modes', is_enabled=False)
        self._note_modes.add_mode(
            'scale',
            AddLayerMode(self._clip_actions,
                         Layer(delete_button='clear_button')))
        self._note_modes.add_mode(
            'drum',
            AddLayerMode(
                self._drum_group,
                Layer(scroll_up_button='left_button',
                      scroll_down_button='right_button',
                      scroll_page_up_button='up_button',
                      scroll_page_down_button='down_button',
                      delete_button='clear_button')))

    def _create_main_modes(self):
        self._main_modes = ModesComponent(name='Main_Modes', is_enabled=False)
        suppressed_arrow_button_mode = (AddLayerMode(
            self._background,
            Layer(left_button='left_button',
                  right_button='right_button',
                  up_button='up_button',
                  down_button='down_button')), )
        self._main_modes.add_mode('none', suppressed_arrow_button_mode)
        self._main_modes.add_mode('fader', None)
        self._main_modes.add_mode('session', self._session_modes)
        self._main_modes.add_mode('note',
                                  (self._note_modes, self._clip_actions))
        self._main_modes.add_mode('chord', suppressed_arrow_button_mode)
        self._main_modes.selected_mode = 'session'
        self._main_modes.set_enabled(True)
        self._Launchpad_Pro_MK3__on_main_mode_changed.subject = self._main_modes

    @listens('selected_mode')
    def __on_main_mode_changed(self, mode):
        if mode == 'session':
            self._session_modes.selected_mode = 'launch'
        self._recording_modes.selected_mode = 'session' if mode == 'session' else 'track'
        self._update_controlled_track()
        self._auto_arm.set_enabled(self._is_instrument_mode())

    @listens('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 = 'fader'
        else:
            self._layout_to_restore = value
            if self._mixer_modes.selected_mode in FADER_MODES:
                self._mixer_modes.selected_mode = '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 = '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 = 'drum' if drum_group_valid else '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)
コード例 #11
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.__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.__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.__on_main_mode_changed.subject = self._main_modes
        return

    @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)
コード例 #12
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)
コード例 #13
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_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._on_device_changed.subject = self._device_provider
        self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Morph ' + VERSION +
                         ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
        self.show_message('Morph ' + VERSION + ' 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'
        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 = [[
            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=CHANNEL,
                               identifier=MORPH_KEYS[index],
                               name='Key_' + str(index),
                               skin=self._skin,
                               resource_type=resource) for index in range(25)
        ]
        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_drum_group(self):
        self._drum_group = MorphDrumGroup(
            set_pad_translations=self.set_pad_translations,
            translation_channel=PAD_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_drum_group2(self):
        self._drum_group2 = MorphDrumGroup(
            set_pad_translations=self.set_pad_translations,
            translation_channel=DRUM_TRANSLATION_CHANNEL)
        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.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._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_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._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._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 _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 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 == NO_OVERLAY:
                debug('no overlay...')
                self._main_modes.selected_mode = 'disabled'
コード例 #14
0
ファイル: Cntrlr.py プロジェクト: thomasf/m4m8
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()
コード例 #15
0
ファイル: Twister.py プロジェクト: amuntner/m4m7
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()
コード例 #16
0
class DeviceNavigationComponent(DeviceNavigationComponentBase):
    __events__ = (u'drum_pad_selection',
                  u'mute_solo_stop_cancel_action_performed')

    def __init__(self,
                 device_bank_registry=None,
                 banking_info=None,
                 delete_handler=None,
                 track_list_component=None,
                 *a,
                 **k):
        assert banking_info is not None
        assert device_bank_registry is not None
        assert track_list_component is not None
        self._flattened_chain = FlattenedDeviceChain(collect_devices)
        self._track_decorator = DecoratorFactory()
        self._modes = NullModes()
        self.move_device = None
        super(DeviceNavigationComponent,
              self).__init__(item_provider=self._flattened_chain, *a, **k)
        self._delete_handler = delete_handler
        self.chain_selection = ChainSelectionComponent(parent=self,
                                                       is_enabled=False)
        self.bank_selection = BankSelectionComponent(
            bank_registry=device_bank_registry,
            banking_info=banking_info,
            device_options_provider=self._device_component,
            is_enabled=False,
            parent=self)
        self.move_device = MoveDeviceComponent(parent=self, is_enabled=False)
        self._last_pressed_button_index = -1
        self._selected_on_previous_press = None
        self._modes = ModesComponent(parent=self)
        self._modes.add_mode(u'default', [
            partial(self.chain_selection.set_parent, None),
            partial(self.bank_selection.set_device, None)
        ])
        self._modes.add_mode(u'chain_selection', [self.chain_selection])
        self._modes.add_mode(u'bank_selection', [self.bank_selection])
        self._modes.selected_mode = u'default'
        self.register_disconnectable(self._flattened_chain)
        self.__on_items_changed.subject = self
        self.__on_bank_selection_closed.subject = self.bank_selection
        self._update_selected_track()
        self._track_list = track_list_component
        watcher = self.register_disconnectable(
            DeviceChainStateWatcher(device_navigation=self))
        self.__on_device_item_state_changed.subject = watcher
        self._update_device()
        self._update_button_colors()

    @property
    def modes(self):
        return self._modes

    def _in_device_enabling_mode(self):
        return self._track_list.selected_mode == u'mute'

    def _on_select_button_pressed(self, button):
        device_or_pad = self.items[button.index].item
        if self._in_device_enabling_mode():
            self._toggle_device(device_or_pad)
            self.notify_mute_solo_stop_cancel_action_performed()
        else:
            self._last_pressed_button_index = button.index
            if not self._delete_handler or not self._delete_handler.is_deleting:
                self._selected_on_previous_press = device_or_pad if self.selected_object != device_or_pad else None
                self._select_item(device_or_pad)

    def _on_select_button_released_immediately(self, button):
        if not self._in_device_enabling_mode():
            self._last_pressed_button_index = -1
            device_or_pad = self.items[button.index].item
            if self._delete_handler and self._delete_handler.is_deleting:
                self._delete_item(device_or_pad)
            elif self.selected_object == device_or_pad and device_or_pad != self._selected_on_previous_press:
                self._on_reselecting_object(device_or_pad)
            self._selected_on_previous_press = None

    def _on_select_button_pressed_delayed(self, button):
        if not self._in_device_enabling_mode():
            self._on_pressed_delayed(self.items[button.index].item)

    def _on_select_button_released(self, button):
        if button.index == self._last_pressed_button_index:
            self._modes.selected_mode = u'default'
            self._last_pressed_button_index = -1
            self._end_move_device()

    @dispatch(Live.DrumPad.DrumPad)
    def _toggle_device(self, drum_pad):
        if liveobj_valid(drum_pad):
            drum_pad.mute = not drum_pad.mute

    @dispatch(object)
    def _toggle_device(self, device):
        if liveobj_valid(device) and device.parameters[0].is_enabled:
            set_enabled(device, not is_on(device))

    @listens(u'state')
    def __on_device_item_state_changed(self):
        self._update_button_colors()

    @listens(u'items')
    def __on_items_changed(self):
        new_items = map(lambda x: x.item, self.items)
        lost_selection_on_empty_pad = new_items and is_drum_pad(
            new_items[-1]
        ) and self._flattened_chain.selected_item not in new_items
        if self._should_select_drum_pad() or lost_selection_on_empty_pad:
            self._select_item(self._current_drum_pad())
        if self.moving:
            self._show_selected_item()
        self.notify_drum_pad_selection()

    def _create_slot(self, index, item, nesting_level):
        items = self._item_provider.items[self.item_offset:]
        num_slots = min(self._num_visible_items, len(items))
        slot = None
        if index == 0 and self.can_scroll_left():
            slot = IconItemSlot(icon=u'page_left.svg')
            slot.is_scrolling_indicator = True
        elif index == num_slots - 1 and self.can_scroll_right():
            slot = IconItemSlot(icon=u'page_right.svg')
            slot.is_scrolling_indicator = True
        else:
            slot = ItemSlot(item=item, nesting_level=nesting_level)
            slot.is_scrolling_indicator = False
        return slot

    @listenable_property
    def moving(self):
        return self.move_device.is_enabled()

    @property
    def device_selection_update_allowed(self):
        return not self._should_select_drum_pad()

    def _color_for_button(self, button_index, is_selected):
        item = self.items[button_index]
        device_or_pad = item.item
        is_active = liveobj_valid(device_or_pad) and is_active_element(
            device_or_pad)
        chain = find_chain_or_track(device_or_pad)
        if not is_active:
            return u'DefaultButton.Off'
        elif is_selected:
            return u'ItemNavigation.ItemSelected'
        elif liveobj_valid(chain):
            return IndexedColor.from_live_index(chain.color_index,
                                                DISPLAY_BUTTON_SHADE_LEVEL)
        else:
            return u'ItemNavigation.ItemNotSelected'

    def _begin_move_device(self, device):
        if not self.move_device.is_enabled(
        ) and device.type != Live.Device.DeviceType.instrument:
            self.move_device.set_device(device)
            self.move_device.set_enabled(True)
            self._scroll_overlay.set_enabled(False)
            self.notify_moving()

    def _end_move_device(self):
        if self.move_device and self.move_device.is_enabled():
            self.move_device.set_device(None)
            self.move_device.set_enabled(False)
            self._scroll_overlay.set_enabled(True)
            self.notify_moving()

    def request_drum_pad_selection(self):
        self._current_track().drum_pad_selected = True

    def unfold_current_drum_pad(self):
        self._current_track().drum_pad_selected = False
        self._current_drum_pad(
        ).canonical_parent.view.is_showing_chain_devices = True

    def sync_selection_to_selected_device(self):
        self._update_item_provider(
            self.song.view.selected_track.view.selected_device)

    @property
    def is_drum_pad_selected(self):
        return is_drum_pad(self._flattened_chain.selected_item)

    @property
    def is_drum_pad_unfolded(self):
        selection = self._flattened_chain.selected_item
        assert is_drum_pad(selection)
        return drum_rack_for_pad(selection).view.is_showing_chain_devices

    def _current_track(self):
        return self._track_decorator.decorate(
            self.song.view.selected_track,
            additional_properties={u'drum_pad_selected': False})

    def _should_select_drum_pad(self):
        return self._current_track().drum_pad_selected

    def _current_drum_pad(self):
        return find_drum_pad(self.items)

    def _update_selected_track(self):
        self._selected_track = self.song.view.selected_track
        selected_track = self._current_track()
        self.reset_offset()
        self._flattened_chain.set_device_parent(selected_track)
        self._device_selection_in_track_changed.subject = selected_track.view
        self._modes.selected_mode = u'default'
        self._end_move_device()
        self._restore_selection(selected_track)

    def _restore_selection(self, selected_track):
        to_select = None
        if self._should_select_drum_pad():
            to_select = self._current_drum_pad()
        if to_select == None:
            to_select = selected_track.view.selected_device
        self._select_item(to_select)

    def back_to_top(self):
        pass

    @property
    def selected_object(self):
        selected_item = self.item_provider.selected_item
        return getattr(selected_item, u'proxied_object', selected_item)

    @dispatch(Live.DrumPad.DrumPad)
    def _do_select_item(self, pad):
        self._current_track().drum_pad_selected = True
        device = self._first_device_on_pad(pad)
        self._appoint_device(device)

    def _first_device_on_pad(self, drum_pad):
        chain = drum_rack_for_pad(drum_pad).view.selected_chain
        if chain and chain.devices:
            return first(chain.devices)

    def _appoint_device(self, device):
        if self._device_component.device_changed(device):
            self._device_component.set_device(device)

    @dispatch(object)
    def _do_select_item(self, device):
        self._current_track().drum_pad_selected = False
        appointed_device = device_to_appoint(device)
        self._appoint_device(appointed_device)
        self.song.view.select_device(device, False)
        self.song.appointed_device = appointed_device

    @dispatch(Live.DrumPad.DrumPad)
    def _on_reselecting_object(self, drum_pad):
        rack = drum_rack_for_pad(drum_pad)
        self._toggle(rack)
        if rack.view.is_showing_chain_devices:
            first_device = self._first_device_on_pad(drum_pad)
            if first_device:
                self._select_item(first_device)
        self.notify_drum_pad_selection()

    @dispatch(object)
    def _on_reselecting_object(self, device):
        if liveobj_valid(device) and device.can_have_chains:
            if not device.can_have_drum_pads:
                self._toggle(device)
        else:
            self.bank_selection.set_device(device)
            self._modes.selected_mode = u'bank_selection'

    @dispatch(Live.DrumPad.DrumPad)
    def _on_pressed_delayed(self, _):
        pass

    @dispatch(object)
    def _on_pressed_delayed(self, device):
        self._show_chains(device)
        self._begin_move_device(device)

    @dispatch(Live.DrumPad.DrumPad)
    def _delete_item(self, pad):
        pass

    @dispatch(object)
    def _delete_item(self, device):
        delete_device(device)

    def _show_chains(self, device):
        if device.can_have_chains:
            self.chain_selection.set_parent(device)
            self._modes.selected_mode = u'chain_selection'

    @listens(u'back')
    def __on_bank_selection_closed(self):
        self._modes.selected_mode = u'default'

    def _update_device(self):
        if not self._should_select_drum_pad(
        ) and not self._is_drum_rack_selected():
            self._modes.selected_mode = u'default'
            self._update_item_provider(self._device_component.device())

    def _is_drum_rack_selected(self):
        selected_item = self._flattened_chain.selected_item
        instrument = self._find_top_level_instrument()
        return liveobj_valid(selected_item) and isinstance(
            selected_item, Live.RackDevice.RackDevice
        ) and selected_item.can_have_drum_pads and not liveobj_changed(
            selected_item, instrument)

    def _find_top_level_instrument(self):
        return find_if(
            lambda device: device.type == Live.Device.DeviceType.instrument,
            self._current_track().devices)

    @listens(u'selected_device')
    def _device_selection_in_track_changed(self):
        new_selection = self.song.view.selected_track.view.selected_device
        if self._can_update_device_selection(new_selection):
            self._modes.selected_mode = u'default'
            self._update_item_provider(new_selection)

    def _toggle(self, item):
        view = item.view
        if view.is_collapsed:
            view.is_collapsed = False
            view.is_showing_chain_devices = True
        else:
            view.is_showing_chain_devices = not view.is_showing_chain_devices

    def _can_update_device_selection(self, new_selection):
        can_update = liveobj_valid(new_selection)
        drum_pad_selected_or_requested = self.is_drum_pad_selected or self._should_select_drum_pad(
        )
        if can_update and drum_pad_selected_or_requested:
            if is_empty_rack(new_selection):
                can_update = False
            if can_update and self.is_drum_pad_selected:
                can_update = not is_first_device_on_pad(
                    new_selection, self._flattened_chain.selected_item)
        elif not can_update and not drum_pad_selected_or_requested:
            can_update = True
        return can_update

    def _update_item_provider(self, selection):
        self._flattened_chain.selected_item = selection
        if not is_drum_pad(selection):
            self._current_track().drum_pad_selected = False
        self.notify_drum_pad_selection()
コード例 #17
0
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))
コード例 #18
0
class KompleteKontrolBase(ControlSurface):
    mixer_component_class = MixerComponent
    channel_strip_component_class = ChannelStripComponent
    is_s_mk2 = False

    def __init__(self, *a, **k):
        super(KompleteKontrolBase, self).__init__(*a, **k)
        with self.component_guard():
            self._create_controls()
            self._create_components()
            self.__on_main_view_changed.subject = self.application.view
        self._handshake_response_pending = False
        self._handshake_task = self._tasks.add(task.run(self._send_handshake))
        self._handshake_task.kill()

    def disconnect(self):
        self._auto_arm.set_enabled(False)
        self._send_midi(GOODBYE_MESSAGE)
        super(KompleteKontrolBase, self).disconnect()

    def port_settings_changed(self):
        self.set_components_enabled(False)
        self._handshake_task.restart()

    def _send_handshake(self):
        self._handshake_response_pending = True
        self._handshake_control.send_value(0, force=True)

    @listens(u'value')
    def _on_handshake_response(self, _):
        self._handshake_task.kill()
        if self._handshake_response_pending:
            self._handshake_response_pending = False
            self.set_components_enabled(True)
            self.refresh_state()

    def set_components_enabled(self, enabled):
        with self.component_guard():
            for c in self._components:
                c.set_enabled(enabled)

    def _create_controls(self):
        self._play_button = MultiElement(create_button(16, u'Play_Button'), create_button(17, u'Play_Button_With_Shift'))
        self._record_button = create_button(18, u'Record_Button')
        self._count_in_button = create_button(19, u'Count_In_Button')
        self._stop_button = create_button(20, u'Stop_Button')
        self._clear_button = create_button(21, u'Clear_Button')
        self._loop_button = create_button(22, u'Loop_Button')
        self._metronome_button = create_button(23, u'Metronome_Button')
        self._tap_tempo_button = create_button(24, u'Tap_Tempo_Button')
        self._undo_button = create_button(32, u'Undo_Button')
        self._redo_button = create_button(33, u'Redo_Button')
        self._quantize_button = create_button(34, u'Quantize_Button')
        self._automation_button = create_button(35, u'Automation_Button')
        self._clip_launch_button = create_button(96, u'Clip_Launch_Button')
        self._track_stop_button = create_button(97, u'Track_Stop_Button')
        self._jump_encoder = create_encoder(52, u'Jump_Encoder')
        self._loop_encoder = create_encoder(53, u'Loop_Encoder')
        self._volume_encoders = ButtonMatrixElement(rows=[[ create_encoder(index + 80, u'Volume_Encoder_{}'.format(index), is_s_mk2=self.is_s_mk2) for index in xrange(NUM_TRACKS) ]], name=u'Volume_Encoders')
        self._pan_encoders = ButtonMatrixElement(rows=[[ create_encoder(index + 88, u'Pan_Encoder_{}'.format(index), is_s_mk2=self.is_s_mk2) for index in xrange(NUM_TRACKS) ]], name=u'Pan_Encoders')
        self._track_name_displays = ButtonMatrixElement(rows=[[ create_display_line(sysex.TRACK_NAME_DISPLAY_HEADER, index, u'Track_Name_Display_{}'.format(index), width=33 if self.is_s_mk2 else 11) for index in xrange(NUM_TRACKS) ]], name=u'Track_Name_Displays')
        self._track_volume_displays = ButtonMatrixElement(rows=[[ create_display_line(sysex.TRACK_VOLUME_DISPLAY_HEADER, index, u'Track_Volume_Display_{}'.format(index), width=12) for index in xrange(NUM_TRACKS) ]], name=u'Track_Volume_Displays')
        self._track_panning_displays = ButtonMatrixElement(rows=[[ create_display_line(sysex.TRACK_PANNING_DISPLAY_HEADER, index, u'Track_Panning_Display_{}'.format(index), width=12) for index in xrange(NUM_TRACKS) ]], name=u'Track_Panning_Displays')
        self._track_type_displays = ButtonMatrixElement(rows=[[ create_sysex_element(sysex.TRACK_TYPE_DISPLAY_HEADER, index, u'Track_Type_Display_{}'.format(index)) for index in xrange(NUM_TRACKS) ]], name=u'Track_Type_Displays')
        self._track_mute_displays = ButtonMatrixElement(rows=[[ create_sysex_element(sysex.TRACK_MUTE_DISPLAY_HEADER, index, u'Track_Mute_Display_{}'.format(index)) for index in xrange(NUM_TRACKS) ]], name=u'Track_Mute_Displays')
        self._track_solo_displays = ButtonMatrixElement(rows=[[ create_sysex_element(sysex.TRACK_SOLO_DISPLAY_HEADER, index, u'Track_Solo_Display_{}'.format(index)) for index in xrange(NUM_TRACKS) ]], name=u'Track_Solo_Displays')
        self._track_muted_via_solo_displays = ButtonMatrixElement(rows=[[ create_sysex_element(sysex.TRACK_MUTED_VIA_SOLO_DISPLAY_HEADER, index, u'Track_Muted_via_Solo_Display_{}'.format(index)) for index in xrange(NUM_TRACKS) ]], name=u'Track_Muted_via_Solo_Displays')
        self._track_selection_displays = ButtonMatrixElement(rows=[[ create_sysex_element(sysex.TRACK_SELECT_DISPLAY_HEADER, index, u'Track_Selection_Display_{}'.format(index)) for index in xrange(NUM_TRACKS) ]], name=u'Track_Selection_Displays')
        self._focus_follow_control = SysexElement(lambda value: sysex.TRACK_CHANGED_DISPLAY_HEADER + value + (midi.SYSEX_END,), name=u'Focus_Follow_Control')
        self._handshake_control = create_button(1, u'Handshake_Control')
        self._handshake_control.reset = nop
        self._on_handshake_response.subject = self._handshake_control

    def _create_components(self):
        self._create_mixer()
        self._create_transport()
        self._create_session_recording()
        self._create_undo_redo()
        self._create_clip_launch()
        self._create_clip_launch_background()
        self._create_detail_clip()
        self._create_focus_follow()
        self._create_auto_arm()
        self._create_view_based_modes()

    def _create_mixer(self):
        self._session_ring = SelectionLinkedSessionRingComponent(name=u'Session_Ring', num_tracks=NUM_TRACKS, tracks_to_use=partial(tracks_to_use_from_song, self.song), always_snap_track_offset=True)
        self._mixer = self.mixer_component_class(name=u'Mixer', tracks_provider=self._session_ring, track_assigner=SimpleTrackAssigner(), channel_strip_component_type=self.channel_strip_component_class, is_enabled=False, layer=self._create_mixer_component_layer())

    def _create_mixer_component_layer(self):
        return Layer(volume_controls=self._volume_encoders, pan_controls=self._pan_encoders, track_name_displays=self._track_name_displays, track_volume_displays=self._track_volume_displays, track_panning_displays=self._track_panning_displays, track_type_displays=self._track_type_displays, track_selection_displays=self._track_selection_displays, track_mute_displays=self._track_mute_displays, track_solo_displays=self._track_solo_displays, track_muted_via_solo_displays=self._track_muted_via_solo_displays)

    def _create_transport(self):
        self._transport = TransportComponent(name=u'Transport', is_enabled=False, layer=Layer(play_button=self._play_button, stop_button=self._stop_button, loop_button=self._loop_button, metronome_button=self._metronome_button, tap_tempo_button=self._tap_tempo_button, jump_encoder=self._jump_encoder, loop_start_encoder=self._loop_encoder))

    def _create_session_recording(self):
        self._session_recording = SessionRecordingComponent(name=u'Session_Recording', is_enabled=False, layer=Layer(automation_button=self._automation_button))

    def _create_undo_redo(self):
        self._undo_redo = UndoRedoComponent(name=u'Undo_Redo', is_enabled=False, layer=Layer(undo_button=self._undo_button, redo_button=self._redo_button))

    def _create_clip_launch(self):
        self._clip_launch = ClipLaunchComponent(name=u'Clip_Launch', is_enabled=False, layer=Layer(clip_launch_button=self._clip_launch_button, track_stop_button=self._track_stop_button))

    def _create_clip_launch_background(self):
        self._clip_launch_background = BackgroundComponent(name=u'Background', is_enabled=False, add_nop_listeners=True, layer=Layer(clip_launch_button=self._clip_launch_button, track_stop_button=self._track_stop_button, priority=-1))

    def _create_detail_clip(self):
        self._detail_clip = DetailClipComponent(name=u'Detail_Clip', is_enabled=False, layer=Layer(quantize_notes_button=self._quantize_button, delete_notes_button=self._clear_button))

    def _create_focus_follow(self):
        self._focus_follow = FocusFollowComponent(name=u'Focus_Follow', is_enabled=False, layer=Layer(focus_follow_control=self._focus_follow_control))

    def _create_auto_arm(self):
        self._auto_arm = AutoArmComponent(name=u'Auto_Arm', is_enabled=False)

    def _create_view_based_modes(self):
        self._view_based_modes = ModesComponent(is_enabled=False)
        self._view_based_modes.add_mode(u'session', (EnablingMode(self._clip_launch), AddLayerMode(self._transport, Layer(session_record_button=self._record_button, record_button=self._count_in_button))))
        self._view_based_modes.add_mode(u'arrange', AddLayerMode(self._transport, Layer(record_button=self._record_button, session_record_button=self._count_in_button)))
        self.__on_main_view_changed()

    @listens(u'is_view_visible', u'Session')
    def __on_main_view_changed(self):
        if self.application.view.is_view_visible(u'Session'):
            self._view_based_modes.selected_mode = u'session'
        else:
            self._view_based_modes.selected_mode = u'arrange'
コード例 #19
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)
	
	"""
コード例 #20
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 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 = 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._modHandle = ModControl(modscript=self,
                                     monomodular=self.monomodular,
                                     name='ModHandle')
        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):
        """
		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))
コード例 #21
0
ファイル: Cntrlr.py プロジェクト: amuntner/m4m7
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
コード例 #22
0
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')
コード例 #23
0
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)
コード例 #24
0
ファイル: MonoPedal.py プロジェクト: aumhaa/m4m8
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)
        # logger.info('initializing debug...')
        # debug = initialize_debug()
        #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)
コード例 #25
0
ファイル: AumPush2.py プロジェクト: amuntner/m4m7
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()
	

	#no idea why this is messing up the stock colors?
	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)
		#debug('mod task group:', self.modhandler.parent_task_group)
		self.modhandler.name = 'ModHandler'
		self.modhandler.layer = Layer( priority = 6, lock_button = self.elements.note_mode_button, grid = self.elements.matrix, 
																			shift_button = self.elements.shift_button, 
																			alt_button = self.elements.select_button,
																			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.layer.priority = 0
		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, 
																			device_selector_matrix = self.elements.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 _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._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, 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
		self._model.mixerView.trackControlView = track_mixer_control
		self._mix_modes = ModesComponent(is_enabled=False)
		self._mix_modes.add_mode('global', self._mixer_control)
		self._mix_modes.add_mode('track', track_mixer_control)
		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, tuple([self._check_track_mixer_entry, self._check_track_mixer_exit]), SetAttributeMode(obj=self._note_editor_settings_component, attribute='parameter_provider', value=self._track_parameter_provider)], behaviour=MixModeBehaviour())
	"""


	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, 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):

		self._crossfader_strip = TouchStripControllerComponent()
		self._crossfader_strip.layer = Layer(touch_strip = self.elements.touch_strip_control)
		self._crossfader_strip.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)

		static_modes = CompoundMode(tuple([self._grab_crossfader, self._release_crossfader]), self._crossfader_strip, self._device_selector, self._send_reset)
		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(priority = 6, cycle_mode_button = 'master_select_button')
		self._troll_modes.selected_mode = 'disabled'

		#self.schedule_message(5, self._remove_pedal)
	

	@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._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()
	

	"""
	@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')
コード例 #26
0
ファイル: OhmModes.py プロジェクト: NSGoat/m4m8
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=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(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))
コード例 #27
0
class Push2(IdentifiableControlSurface, PushBase):
    session_component_type = SessionComponent
    drum_group_note_editor_skin = 'DrumGroupNoteEditor'
    input_target_name_for_auto_arm = 'Push2 Input'
    RESEND_MODEL_DATA_TIMEOUT = 5.0

    def __init__(self, c_instance = None, model = None, *a, **k):
        raise model is not None or AssertionError
        self._model = model
        self._double_click_context = DoubleClickContext()
        self._real_time_mapper = c_instance.real_time_mapper
        self._device_decorator_factory = DeviceDecoratorFactory()
        self._clip_decorator_factory = ClipDecoratorFactory()
        self._real_time_data_list = []
        super(Push2, self).__init__(c_instance=c_instance, product_id_bytes=sysex.IDENTITY_RESPONSE_PRODUCT_ID_BYTES, *a, **k)
        self._board_revision = 0
        self._firmware_version = FirmwareVersion(0, 0, 0)
        self._real_time_client = RealTimeClientModel()
        self._connected = False
        self._identified = False
        self._initialized = False
        self.register_disconnectable(model)
        self.register_disconnectable(self._device_decorator_factory)
        with self.component_guard():
            self._model.realTimeClient = self._real_time_client
            self._real_time_client.clientId = self._real_time_mapper.client_id
        logger.info('Push 2 script loaded')

    def initialize(self):
        if not self._initialized:
            self._initialized = True
            self._init_hardware_settings()
            self._init_pad_curve()
            self._hardware_settings.fade_in_led_brightness(self._setup_settings.hardware.led_brightness)
            self._pad_curve_sender.send()
            self._send_color_palette()
            super(Push2, self).initialize()
            self.__on_selected_track_frozen_changed.subject = self.song.view
            self.__on_selected_track_frozen_changed()
            self._switch_to_live_mode()
            self._user.defer_sysex_sending = True
            self.update()
        if self._firmware_update.provided_version > self._firmware_version and self._board_revision > 0 and self._identified:
            self._firmware_update.start()

    def _try_initialize(self):
        if self._connected and self._identified:
            self.initialize()

    def on_process_state_changed(self, state):
        StateEnum = MidiRemoteScript.Push2ProcessState
        self._connected = state == StateEnum.connected
        if state == StateEnum.died:
            self._c_instance.launch_external_process()
        if state == StateEnum.connected:
            with self.component_guard():
                self._try_initialize()
            self._model.commit_changes(send_all=True)

    def on_user_data_arrived(self, message):
        if self._initialized:
            data = json.loads(message)
            self._process_qml_errors(data)
            self._firmware_update.process_firmware_response(data)

    def _process_qml_errors(self, data):
        qmlerrors = [ entry['description'] for entry in data if entry['type'] == 'qmlerror' ]
        if qmlerrors:
            raise QmlError('\n'.join(qmlerrors))

    def disconnect(self):
        self.__on_before_push_mode_sent.subject = None
        super(Push2, self).disconnect()
        self.__dict__.clear()
        logger.info('Push 2 script unloaded')

    def register_real_time_data(self, real_time_data):
        self._real_time_data_list.append(real_time_data)

    def _commit_real_time_data_changes(self):
        for d in self._real_time_data_list:
            d.update_attachment()

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

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

    def _create_components(self):
        self._init_dialog_modes()
        super(Push2, self)._create_components()
        self._init_browser()
        self._init_session_ring_selection_linking()
        self._init_setup_component()
        self._init_firmware_update()
        self._init_convert_enabler()

    @contextmanager
    def _component_guard(self):
        with super(Push2, self)._component_guard():
            with inject(real_time_mapper=const(self._c_instance.real_time_mapper)).everywhere():
                yield
                self._commit_real_time_data_changes()
                self._model.commit_changes()

    def _create_notification_component(self):
        notification = NotificationComponent(is_root=True)
        self._model.notificationView = notification
        return notification

    def _create_background_layer(self):
        return super(Push2, self)._create_background_layer() + Layer(mix_button='mix_button', page_left_button='page_left_button', page_right_button='page_right_button', mute_button='global_mute_button', solo_button='global_solo_button', track_stop_button='global_track_stop_button', convert_button='convert_button', layout_button='layout_button', setup_button='setup_button')

    def _create_message_box_background_layer(self):
        return super(Push2, self)._create_message_box_background_layer() + BackgroundLayer('mix_button', 'page_left_button', 'page_right_button', 'convert_button', 'layout_button', 'setup_button')

    def _create_message_box_layer(self):
        return Layer(cancel_button='track_state_buttons_raw[0]', priority=consts.MESSAGE_BOX_PRIORITY)

    def _init_message_box(self):
        super(Push2, self)._init_message_box()
        self._model.liveDialogView = self._dialog._message_box

    def _create_mixer(self):
        return MixerComponent(is_root=True, tracks_provider=self._session_ring, solo_layer=Layer(solo_buttons='select_buttons'), mute_layer=Layer(mute_buttons='select_buttons'))

    def _create_convert(self):
        convert = ConvertComponent(decorator_factory=self._device_decorator_factory, name='Convert', tracks_provider=self._session_ring, is_enabled=False, layer=make_dialog_layer(action_buttons='select_buttons', cancel_button='track_state_buttons_raw[0]'))
        self.__on_convert_closed.subject = convert
        self._model.convertView = convert
        return convert

    def _init_note_settings_component(self):
        self._note_settings_component = NoteSettingsComponent(grid_resolution=self._grid_resolution, is_enabled=False, layer=Layer(full_velocity_button='accent_button', priority=consts.MOMENTARY_DIALOG_PRIORITY))
        self._model.noteSettingsView = self._note_settings_component

    def _init_note_editor_settings_component(self):
        super(Push2, self)._init_note_editor_settings_component()
        self._model.stepSettingsView = self._note_editor_settings_component.step_settings

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

    def _init_convert_enabler(self):
        self._convert_enabler = ConvertEnabler(is_root=True, is_enabled=True, enter_dialog_mode=self._enter_dialog_mode, exit_dialog_mode=self._exit_dialog_mode)
        self._convert_enabler.layer = Layer(convert_toggle_button='convert_button')

    @listens('cancel')
    def __on_convert_closed(self):
        self._dialog_modes.selected_mode = None

    def _init_main_modes(self):
        super(Push2, self)._init_main_modes()
        self._main_modes.add_mode('user', [self._user_mode_ui_blocker])
        self._model.modeState = self.register_disconnectable(ModeCollector(main_modes=self._main_modes, mix_modes=self._mix_modes, global_mix_modes=self._mixer_control, device_modes=self._device_navigation.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,
         self.elements.create_device_button,
         self.elements.create_track_button])

    @listens_group('value')
    def __on_main_mode_button_value(self, value, sender):
        if not value:
            self._exit_modal_modes()

    def _exit_modal_modes(self):
        self._dialog_modes.selected_mode = None
        self._setup_enabler.selected_mode = 'disabled'

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

    def _init_stop_clips_action(self):
        stop_clips_buttons = ButtonMatrixElement(rows=[wrap_button('select_buttons_raw', 'global_track_stop_button')])
        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'), stop_selected_track_clip_button='global_track_stop_button', stop_track_clips_buttons=stop_clips_buttons)

    def _init_mixer(self):
        self._mixer = self._create_mixer()
        self._mixer.add_mode('stop', self._stop_clips)
        self._mixer.stop_button.mode_unselected_color = 'DefaultButton.On'
        self._mixer.layer = Layer(solo_track_button='global_solo_button', mute_track_button='global_mute_button', stop_button='global_track_stop_button')
        self._mixer_solo_layer = self._create_mixer_solo_layer()
        self._mixer_mute_layer = self._create_mixer_mute_layer()
        self._mixer.master_strip().name = 'Master_Channel_strip'
        self._master_selector = MasterTrackComponent(tracks_provider=self._session_ring, is_enabled=False, layer=Layer(toggle_button='master_select_button'))
        self._master_selector.set_enabled(True)
        self._model.mixerButtonState = self._mixer.mixer_button_state
        self._mixer.set_enabled(True)

    def _create_instrument_layer(self):
        return super(Push2, self)._create_instrument_layer() + Layer(prev_loop_page_button='page_left_button', next_loop_page_button='page_right_button')

    def _create_step_sequencer_layer(self):
        return super(Push2, self)._create_step_sequencer_layer() + Layer(prev_loop_page_button='page_left_button', next_loop_page_button='page_right_button')

    def _create_session(self):
        session = super(Push2, self)._create_session()
        for scene_ix in xrange(8):
            scene = session.scene(scene_ix)
            for track_ix in xrange(8):
                clip_slot = scene.clip_slot(track_ix)
                clip_slot.set_decorator_factory(self._clip_decorator_factory)

        return session

    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='page_left_button', page_right_button='page_right_button', page_up_button='octave_up_button', page_down_button='octave_down_button')

    def on_select_clip_slot(self, clip_slot):
        self.show_notification('Clip Selected: ' + select_clip_and_get_name_from_slot(clip_slot, self.song))

    def on_select_scene(self, scene):
        self.show_notification('Scene Selected: ' + select_scene_and_get_name(scene, self.song))

    def _create_session_mode(self):
        session_modes = ModesComponent(is_enabled=False)
        session_modes.add_mode('session', self._session_mode)
        session_modes.add_mode('overview', self._session_overview_mode)
        session_modes.layer = Layer(cycle_mode_button='layout_button')
        session_modes.selected_mode = 'session'
        return [session_modes, self._session_navigation]

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

    def _create_drum_component(self):
        return DrumGroupComponent(name='Drum_Group', is_enabled=False, notification_formatter=self._drum_pad_notification_formatter(), tracks_provider=self._session_ring, device_decorator_factory=self._device_decorator_factory, quantizer=self._quantize)

    def _create_device_mode(self):
        self._drum_pad_parameter_component = DrumPadParameterComponent(view_model=self._model, is_enabled=False, layer=Layer(choke_encoder='parameter_controls_raw[0]'))
        self._device_or_pad_parameter_chooser = ModesComponent()
        self._device_or_pad_parameter_chooser.add_mode('device', [make_freeze_aware(self._device_parameter_component, self._device_parameter_component.layer), self._device_view])
        self._device_or_pad_parameter_chooser.add_mode('drum_pad', [make_freeze_aware(self._drum_pad_parameter_component, self._drum_pad_parameter_component.layer)])
        self._device_or_pad_parameter_chooser.selected_mode = 'device'
        return [partial(self._view_control.show_view, 'Detail/DeviceChain'),
         self._device_or_pad_parameter_chooser,
         make_freeze_aware(self._device_enabling, self._device_enabling.layer),
         self._setup_freeze_aware_device_navigation(),
         self._device_note_editor_mode,
         SetAttributeMode(obj=self._note_editor_settings_component, attribute='parameter_provider', value=self._device_component)]

    def _setup_freeze_aware_device_navigation(self):

        def create_layer_setter(layer_name, layer):
            return SetAttributeMode(obj=self._device_navigation, attribute=layer_name, value=layer)

        return make_freeze_aware(self._device_navigation, self._device_navigation.layer, default_mode_extras=[create_layer_setter('scroll_right_layer', Layer(button=self.elements.track_state_buttons_raw[-1])), create_layer_setter('scroll_left_layer', Layer(button=self.elements.track_state_buttons_raw[0]))], frozen_mode_extras=[lambda : setattr(self._device_navigation.modes, 'selected_mode', 'default'), create_layer_setter('scroll_right_layer', Layer()), create_layer_setter('scroll_left_layer', Layer())])

    @listens('drum_pad_selection')
    def __on_drum_pad_selection_changed(self):
        if self._device_navigation.is_drum_pad_selected:
            show_pad_parameters = self._device_navigation.is_drum_pad_unfolded
            new_mode = 'drum_pad' if show_pad_parameters else 'device'
            selected_pad = show_pad_parameters and self._device_navigation.item_provider.selected_item
            self._drum_pad_parameter_component.drum_pad = selected_pad
        self._device_or_pad_parameter_chooser.selected_mode = new_mode
        self._automation_component.set_drum_pad_selected(self._device_navigation.is_drum_pad_selected)

    def _init_browser(self):

        class BrowserMode(LazyComponentMode, Disconnectable):

            def __init__(self, model = None, *a, **k):
                raise model is not None or AssertionError
                super(BrowserMode, self).__init__(*a, **k)
                self._model = model

            def enter_mode(self):
                self._model.browserView = self.component
                self._model.browserData = self.component
                super(BrowserMode, self).enter_mode()

            def disconnect(self):
                super(BrowserMode, self).disconnect()
                self._model = None

        self._browser_mode = BrowserMode(self._model, self._create_browser)
        self._new_track_browser_mode = BrowserMode(self._model, self._create_new_track_browser)
        self.register_disconnectable(self._browser_mode)
        self.register_disconnectable(self._new_track_browser_mode)

    def _init_browse_mode(self):

        class BrowserModeBehaviour(ModeButtonBehaviour):

            def press_immediate(self, component, mode):
                if mode == component.selected_mode:
                    component.selected_mode = component.active_modes[0]
                else:
                    component.push_mode(mode)

        browser = Live.Application.get_application().browser

        def clear_hotswap_target():
            browser.hotswap_target = None

        def select_filter_type_for_track():
            has_midi_support = self.song.view.selected_track.has_midi_input
            browser.filter_type = Live.Browser.FilterType.midi_track_devices if has_midi_support else Live.Browser.FilterType.audio_effect_hotswap

        def select_filter_type_for_hotswapping():
            if liveobj_valid(browser.hotswap_target):
                browser.filter_type = Live.Browser.FilterType.disabled
            else:
                select_filter_type_for_track()

        self._main_modes.add_mode('browse', [BrowserHotswapMode(application=self.application()), select_filter_type_for_hotswapping, self._browser_mode], behaviour=BrowserModeBehaviour())
        self._main_modes.add_mode('add_device', [clear_hotswap_target, select_filter_type_for_track, self._browser_mode], behaviour=BrowserModeBehaviour())
        self._main_modes.add_mode('add_track', [clear_hotswap_target, self._new_track_browser_mode], behaviour=BrowserModeBehaviour())

    def _create_browser_layer(self):
        return Layer(up_button='nav_up_button', down_button='nav_down_button', right_button='nav_right_button', left_button='nav_left_button', back_button='track_state_buttons_raw[-2]', open_button='track_state_buttons_raw[-1]', load_button='select_buttons_raw[-1]', scroll_encoders=self.elements.global_param_controls.submatrix[:-1, :], scroll_focused_encoder='parameter_controls_raw[-1]', close_button='track_state_buttons_raw[0]', prehear_button='track_state_buttons_raw[1]')

    def _create_browser(self):
        browser = BrowserComponent(name='Browser', is_enabled=False, preferences=self.preferences, layer=self._create_browser_layer())
        self._on_browser_loaded.add_subject(browser)
        self._on_browser_closed.add_subject(browser)
        return browser

    def _create_new_track_browser(self):
        browser = NewTrackBrowserComponent(name='NewTrackBrowser', is_enabled=False, preferences=self.preferences, layer=self._create_browser_layer())
        self._on_browser_loaded.add_subject(browser)
        self._on_browser_closed.add_subject(browser)
        return browser

    @listens_group('loaded')
    def _on_browser_loaded(self, sender):
        browser = Live.Application.get_application().browser
        if browser.hotswap_target is None:
            self._main_modes.selected_mode = 'device'
        drum_rack = find_drum_group_device(self.song.view.selected_track)
        if drum_rack and is_empty_rack(drum_rack):
            self._device_navigation.request_drum_pad_selection()
        if drum_rack and self._device_navigation.is_drum_pad_selected and not self._device_navigation.is_drum_pad_unfolded:
            self._device_navigation.unfold_current_drum_pad()

    @listens_group('close')
    def _on_browser_closed(self, sender):
        if self._main_modes.selected_mode == 'add_track':
            self._main_modes.selected_mode = self._main_modes.active_modes[0]
        else:
            self._main_modes.selected_mode = 'device'

    def _is_on_master(self):
        return self.song.view.selected_track == self.song.master_track

    def _determine_mix_mode(self):
        selected_mode = self._main_modes.selected_mode
        mix_mode = self._mix_modes.selected_mode
        if selected_mode == 'mix':
            if self._is_on_master():
                if mix_mode == 'global':
                    self._mix_modes.push_mode('track')
            elif mix_mode == 'track' and 'global' in self._mix_modes.active_modes:
                self._mix_modes.pop_mode('track')

    def _on_selected_track_changed(self):
        if self._initialized:
            super(Push2, self)._on_selected_track_changed()
            self._close_browse_mode()
            self._determine_mix_mode()

    def _close_browse_mode(self):
        selected_mode = self._main_modes.selected_mode
        if selected_mode in ('browse', 'add_device', 'add_track'):
            self._main_modes.pop_mode(selected_mode)

    @listens('selected_track.is_frozen')
    def __on_selected_track_frozen_changed(self):
        frozen = self.song.view.selected_track.is_frozen
        self._main_modes.browse_button.enabled = self._main_modes.add_track_button.enabled = self._main_modes.add_device_button.enabled = not frozen
        self._close_browse_mode()

    def _create_device_component(self):
        return DeviceComponent(device_decorator_factory=self._device_decorator_factory, device_bank_registry=self._device_bank_registry, banking_info=BankingInfo(bank_definitions=BANK_DEFINITIONS), 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=Layer(parameter_controls='fine_grain_param_controls'))

    def _create_device_navigation(self):
        self._chain_selection = ChainSelectionComponent(is_enabled=False, layer=Layer(select_buttons='select_buttons'))
        self._chain_selection.scroll_left_layer = Layer(button='select_buttons_raw[0]')
        self._chain_selection.scroll_right_layer = Layer(button='select_buttons_raw[-1]')
        self._bank_selection = BankSelectionComponent(bank_registry=self._device_bank_registry, banking_info=BankingInfo(bank_definitions=BANK_DEFINITIONS), device_options_provider=self._device_component, is_enabled=False, layer=Layer(option_buttons='track_state_buttons', select_buttons='select_buttons', priority=consts.DIALOG_PRIORITY))
        self._bank_selection.scroll_left_layer = Layer(button='select_buttons_raw[0]', priority=consts.DIALOG_PRIORITY)
        self._bank_selection.scroll_right_layer = Layer(button='select_buttons_raw[-1]', priority=consts.DIALOG_PRIORITY)
        move_device = MoveDeviceComponent(is_enabled=False, layer=Layer(move_encoders='global_param_controls'))
        device_navigation = DeviceNavigationComponent(name='DeviceNavigation', device_bank_registry=self._device_bank_registry, device_component=self._device_component, delete_handler=self._delete_component, chain_selection=self._chain_selection, bank_selection=self._bank_selection, move_device=move_device, track_selection=self._track_list_component, is_enabled=False, layer=Layer(select_buttons='track_state_buttons'))
        device_navigation.scroll_left_layer = Layer(button='track_state_buttons_raw[0]')
        device_navigation.scroll_right_layer = Layer(button='track_state_buttons_raw[-1]')
        self._device_enabling = DeviceEnablingComponent(device_navigation=device_navigation, is_enabled=False, layer=Layer(toggle_buttons=ButtonMatrixElement(rows=[wrap_button('track_state_buttons_raw', 'global_mute_button')])))
        self.__on_drum_pad_selection_changed.subject = device_navigation
        self._device_component.allow_update_callback = lambda : device_navigation.device_selection_update_allowed
        return device_navigation

    def _init_device(self):
        super(Push2, self)._init_device()
        self._device_view = DeviceViewComponent(name='DeviceView', device_component=self._device_component, view_model=self._model, is_enabled=False)
        self._model.devicelistView = self._device_navigation
        self._model.chainListView = self._chain_selection
        self._model.parameterBankListView = self._bank_selection
        self._model.editModeOptionsView = self._bank_selection.options

    def _drum_pad_notification_formatter(self):
        return None

    def _create_view_control_component(self):
        return ViewControlComponent(name='View_Control', tracks_provider=self._session_ring)

    def _create_session_recording(self):
        return SessionRecordingComponent(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_session_ring(self):
        self._session_ring = SessionRingTrackProvider(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_ring_selection_linking(self):
        self._sessionring_link = self.register_disconnectable(SessionRingSelectionLinking(session_ring=self._session_ring, selection_changed_notifier=self._view_control))

    def _init_track_list(self):
        track_delete_buttons = ButtonMatrixElement(rows=[wrap_button('select_buttons_raw', 'delete_button')])
        track_duplicate_buttons = ButtonMatrixElement(rows=[wrap_button('select_buttons_raw', 'duplicate_button')])
        track_arm_buttons = ButtonMatrixElement(rows=[wrap_button('select_buttons_raw', 'record_button')])
        self._track_list_component = MixerTrackListComponent(tracks_provider=self._session_ring, trigger_recording_on_release_callback=self._session_recording.set_trigger_recording_on_release, is_enabled=False, layer=Layer(select_buttons='select_buttons', delete_buttons=track_delete_buttons, duplicate_buttons=track_duplicate_buttons, arm_buttons=track_arm_buttons))
        self._model.tracklistView = self._track_list_component

    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 = 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]'))
        self._model.mixerView.trackControlView = track_mixer_control
        self._mix_modes = ModesComponent(is_enabled=False)
        self._mix_modes.add_mode('global', self._mixer_control)
        self._mix_modes.add_mode('track', track_mixer_control)
        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), self._track_list_component], behaviour=MixModeBehaviour())

    def _init_dialog_modes(self):
        self._dialog_modes = ModesComponent(is_root=True)
        self._dialog_modes.add_mode('convert', LazyComponentMode(self._create_convert))
        self.__dialog_mode_button_value.replace_subjects([self.elements.scale_presets_button, self.elements.convert_button])

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

    def _enter_dialog_mode(self, mode_name):
        self._dialog_modes.selected_mode = None if self._dialog_modes.selected_mode == mode_name else mode_name

    def _exit_dialog_mode(self, mode_name):
        if self._dialog_modes.selected_mode == mode_name:
            self._dialog_modes.selected_mode = None

    def _create_scales(self):
        root_note_buttons = ButtonMatrixElement(rows=[self.elements.track_state_buttons_raw[1:-1], self.elements.select_buttons_raw[1:-1]])
        scales = ScalesComponent(note_layout=self._note_layout, is_enabled=False, layer=make_dialog_layer(root_note_buttons=root_note_buttons, in_key_toggle_button='select_buttons_raw[0]', fixed_toggle_button='select_buttons_raw[-1]', scale_encoders=self.elements.global_param_controls.submatrix[1:-1, :], close_button='track_state_buttons_raw[0]'))
        self.__on_scales_closed.subject = scales
        self._model.scalesView = scales
        return scales

    def _init_scales(self):
        self._dialog_modes.add_mode('scales', self._create_scales())
        super(Push2, self)._init_scales()

    def _create_scales_enabler(self):
        return ScalesEnabler(enter_dialog_mode=self._enter_dialog_mode, exit_dialog_mode=self._exit_dialog_mode, is_enabled=False, is_root=True, layer=Layer(toggle_button='scale_presets_button'))

    @listens('close')
    def __on_scales_closed(self):
        self._dialog_modes.selected_mode = None

    def _create_clip_mode(self):
        base_loop_layer = Layer(shift_button='shift_button', loop_button='track_state_buttons_raw[1]', zoom_encoder='fine_grain_param_controls_raw[0]', encoders=self.elements.global_param_controls.submatrix[1:4, :])
        self._loop_controller = LoopSettingsControllerComponent(is_enabled=False)
        self._model.loopSettingsView = self._loop_controller
        audio_clip_layer = Layer(warp_mode_encoder='parameter_controls_raw[5]', transpose_encoder='parameter_controls_raw[6]', detune_encoder=self._with_shift('parameter_controls_raw[6]'), gain_encoder='parameter_controls_raw[7]', shift_button='shift_button')
        audio_clip_controller = AudioClipSettingsControllerComponent(is_enabled=False)
        self._model.audioClipSettingsView = audio_clip_controller
        clip_control_mode_selector = ModesComponent(is_enabled=False)
        clip_control_mode_selector.add_mode('midi', [make_freeze_aware(self._loop_controller, base_loop_layer + Layer(encoders=self.elements.global_param_controls.submatrix[:3, :]))])
        clip_control_mode_selector.add_mode('audio', [make_freeze_aware(self._loop_controller, base_loop_layer + Layer(encoders=self.elements.global_param_controls.submatrix[1:4, :])), make_freeze_aware(audio_clip_controller, audio_clip_layer)])
        clip_control_mode_selector.add_mode('no_clip', [])
        clip_control_mode_selector.selected_mode = 'no_clip'
        clip_control = ClipControlComponent(loop_controller=self._loop_controller, audio_clip_controller=audio_clip_controller, mode_selector=clip_control_mode_selector, decorator_factory=self._clip_decorator_factory, is_enabled=False)
        self._model.clipView = clip_control
        return [clip_control_mode_selector,
         make_freeze_aware(self._loop_controller, base_loop_layer),
         make_freeze_aware(audio_clip_controller, audio_clip_layer),
         clip_control,
         self._track_list_component]

    def _init_quantize_actions(self):
        self._quantize_settings = QuantizationSettingsComponent(name='Quantization_Settings', is_enabled=False, layer=make_dialog_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[4]', record_quantization_toggle_button='track_state_buttons_raw[4]', priority=consts.MOMENTARY_DIALOG_PRIORITY))
        self._model.quantizeSettingsView = self._quantize_settings
        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(Push2, self)._init_fixed_length()
        self._fixed_length_settings_component.layer = make_dialog_layer(length_option_buttons='select_buttons', fixed_length_toggle_button='track_state_buttons_raw[0]', priority=consts.MOMENTARY_DIALOG_PRIORITY)
        self._model.fixedLengthSelectorView = self._fixed_length_settings_component
        self._model.fixedLengthSettings = self._fixed_length_setting

    def _init_value_components(self):
        super(Push2, self)._init_value_components()
        self._model.importantGlobals.swing = self._swing_amount.display
        self._model.importantGlobals.tempo = self._tempo.display
        self._model.importantGlobals.masterVolume = self._master_vol.display
        self._model.importantGlobals.cueVolume = self._master_cue_vol.display

    def _create_main_modes_layer(self):
        return Layer(mix_button='mix_button', clip_button='clip_mode_button', device_button='device_mode_button', browse_button='browse_mode_button', add_device_button='create_device_button', add_track_button='create_track_button')

    def _should_send_palette(self):
        return self._firmware_version <= FirmwareVersion(0, 5, 28)

    def _send_color_palette(self):
        if self._should_send_palette():
            with self.component_guard():
                palette_entry = SysexElement(sysex.make_rgb_palette_entry_message)
                finalize_palette = SysexElement(sysex.make_reapply_palette_message)
                for index, hex_color, white_balance in COLOR_TABLE:
                    palette_entry.send_value(index, hex_color, white_balance)

                finalize_palette.send_value()

    def _init_pad_curve(self):
        self._pad_curve_sender = PadVelocityCurveSender(curve_sysex_element=SysexElement(sysex.make_pad_velocity_curve_message), threshold_sysex_element=SysexElement(sysex.make_pad_threshold_message), settings=self._setup_settings.pad_settings, chunk_size=sysex.PAD_VELOCITY_CURVE_CHUNK_SIZE)

    def _create_user_component(self):
        self._user_mode_ui_blocker = Component(is_enabled=False, layer=self._create_message_box_background_layer())
        sysex_control = SysexElement(send_message_generator=sysex.make_mode_switch_messsage, sysex_identifier=sysex.make_message_identifier(sysex.MODE_SWITCH_MESSAGE_ID))
        user = UserComponent(value_control=sysex_control, is_enabled=True, is_root=True)
        user.layer = Layer(user_mode_toggle_button='user_button', priority=consts.USER_BUTTON_PRIORITY)
        self.__on_before_push_mode_sent.subject = user
        self.__on_after_push_mode_sent.subject = user
        return user

    @listens('before_mode_sent')
    def __on_before_push_mode_sent(self, mode):
        if mode == sysex.USER_MODE and self._main_modes.selected_mode != 'user':
            self._main_modes.push_mode('user')

    @listens('after_mode_sent')
    def __on_after_push_mode_sent(self, mode):
        if mode == sysex.LIVE_MODE and self._main_modes.selected_mode == 'user':
            self._main_modes.pop_mode('user')
        self._user.defer_sysex_sending = mode == sysex.LIVE_MODE

    def _create_settings(self):
        return create_settings(preferences=self.preferences)

    def _init_hardware_settings(self):
        self._setup_settings = self.register_disconnectable(Settings(preferences=self.preferences))
        self._hardware_settings = HardwareSettingsComponent(led_brightness_element=SysexElement(sysex.make_led_brightness_message), display_brightness_element=SysexElement(sysex.make_display_brightness_message), settings=self._setup_settings.hardware)

    def _init_setup_component(self):
        self._setup_settings.general.workflow = 'scene' if self._settings['workflow'].value else 'clip'
        self.__on_workflow_setting_changed.subject = self._setup_settings.general
        setup = SetupComponent(name='Setup', settings=self._setup_settings, pad_curve_sender=self._pad_curve_sender, in_developer_mode=self._c_instance.in_developer_mode, is_enabled=False, layer=make_dialog_layer(category_radio_buttons='select_buttons', priority=consts.SETUP_DIALOG_PRIORITY))
        setup.general.layer = Layer(workflow_encoder='parameter_controls_raw[0]', display_brightness_encoder='parameter_controls_raw[1]', led_brightness_encoder='parameter_controls_raw[2]', priority=consts.SETUP_DIALOG_PRIORITY)
        setup.pad_settings.layer = Layer(sensitivity_encoder='parameter_controls_raw[4]', gain_encoder='parameter_controls_raw[5]', dynamics_encoder='parameter_controls_raw[6]', priority=consts.SETUP_DIALOG_PRIORITY)
        setup.display_debug.layer = Layer(show_row_spaces_button='track_state_buttons_raw[0]', show_row_margins_button='track_state_buttons_raw[1]', show_row_middle_button='track_state_buttons_raw[2]', show_button_spaces_button='track_state_buttons_raw[3]', show_unlit_button_button='track_state_buttons_raw[4]', show_lit_button_button='track_state_buttons_raw[5]', priority=consts.SETUP_DIALOG_PRIORITY)
        setup.profiling.layer = Layer(show_qml_stats_button='track_state_buttons_raw[0]', show_usb_stats_button='track_state_buttons_raw[1]', show_realtime_ipc_stats_button='track_state_buttons_raw[2]', priority=consts.SETUP_DIALOG_PRIORITY)
        self._model.setupView = setup
        self._setup_enabler = EnablingModesComponent(component=setup, enabled_color='DefaultButton.On', disabled_color='DefaultButton.On')
        self._setup_enabler.layer = Layer(cycle_mode_button='setup_button')

    def _init_firmware_update(self):
        self._firmware_update = FirmwareUpdateComponent(layer=self._create_message_box_background_layer())
        self._model.firmwareUpdate = self._firmware_update

    @listens('workflow')
    def __on_workflow_setting_changed(self, value):
        self._settings['workflow'].value = value == 'scene'

    def _create_note_mode(self):

        class NoteLayoutSwitcher(Component):
            cycle_button = ButtonControl()

            def __init__(self, switch_note_mode_layout = None, *a, **k):
                raise switch_note_mode_layout is not None or AssertionError
                super(NoteLayoutSwitcher, self).__init__(*a, **k)
                self._switch_note_mode_layout = switch_note_mode_layout

            @cycle_button.pressed
            def cycle_button(self, button):
                self._switch_note_mode_layout()

        note_layout_switcher = NoteLayoutSwitcher(switch_note_mode_layout=self._switch_note_mode_layout, is_enabled=False, layer=Layer(cycle_button='layout_button'))
        return super(Push2, self)._create_note_mode() + [note_layout_switcher]

    def _create_note_mode_behaviour(self):
        return self._auto_arm.auto_arm_restore_behaviour()

    def _create_controls(self):

        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, playhead=self._c_instance.playhead, model=self._model)
        self.__on_param_encoder_touched.replace_subjects(self.elements.global_param_touch_buttons_raw)
        self._update_encoder_model()

    def _update_full_velocity(self, accent_is_active):
        super(Push2, self)._update_full_velocity(accent_is_active)
        self._slice_step_sequencer.full_velocity = accent_is_active

    def _update_playhead_color(self, color):
        super(Push2, self)._update_playhead_color(color)
        self._slice_step_sequencer.playhead_color = color

    @listens_group('value')
    def __on_param_encoder_touched(self, value, encoder):
        self._update_encoder_model()

    def _update_encoder_model(self):
        self._model.controls.encoders = [ NamedTuple(__id__='encoder_%i' % i, touched=e.is_pressed()) for i, e in enumerate(self.elements.global_param_touch_buttons_raw) ]

    def _with_firmware_version(self, major_version, minor_version, control_element):
        """
        We consider all features to be available for Push 2
        """
        return control_element

    def _send_hardware_settings(self):
        self._hardware_settings.send()
        self._pad_curve_sender.send()
        self._send_color_palette()

    def port_settings_changed(self):
        super(Push2, self).port_settings_changed()
        if self._initialized:
            self._send_hardware_settings()
            self.update()

    def on_identified(self, response_bytes):
        try:
            major, minor, build, sn, board_revision = sysex.extract_identity_response_info(response_bytes)
            self._model.firmwareInfo.major = major
            self._model.firmwareInfo.minor = minor
            self._model.firmwareInfo.build = build
            self._model.firmwareInfo.serialNumber = sn
            logger.info('Push 2 identified')
            logger.info('Firmware %i.%i Build %i' % (major, minor, build))
            logger.info('Serial number %i' % sn)
            logger.info('Board Revision %i' % board_revision)
            self._firmware_version = FirmwareVersion(major, minor, build)
            self._board_revision = board_revision
            self._identified = True
            self._try_initialize()
        except IndexError:
            logger.warning("Couldn't identify Push 2 unit")

    def update(self):
        if self._initialized:
            super(Push2, self).update()

    def request_zoom(self, zoom_factor):
        mode = self._main_modes.selected_mode
        if mode == 'device':
            self._device_component.request_zoom(zoom_factor)
        elif mode == 'clip':
            self._loop_controller.request_zoom(zoom_factor)
コード例 #28
0
ファイル: OhmModes.py プロジェクト: NSGoat/m4m8
class OhmModHandler(ModHandler):
    def __init__(self, *a, **k):
        super(OhmModHandler, self).__init__(*a, **k)
        self._shift_mode = ModesComponent()
        self._color_type = 'RGB'
        self._shift_mode.add_mode(
            'shift',
            tuple([self._enable_shift, self._disable_shift]),
            behaviour=CancellableBehaviourWithRelease())
        self.nav_box = self.register_component(
            NavigationBox(self, 16, 16, 8, 8, self.set_offset))
        self._mod_button = None

    def _enable_shift(self):
        self._shift_value(1)

    def _disable_shift(self):
        self._shift_value(0)

    def set_shift_button(self, button):
        self._shift_mode.shift_button.set_control_element(button)

    def set_nav_matrix(self, matrix):
        self.nav_box.set_matrix(matrix)

    def _receive_grid(self, x, y, value, *a, **k):
        #self._receive_grid(x, y, value, *a, **k)
        legacy = self.active_mod().legacy
        if self._active_mod:
            if not self._grid_value.subject is None:
                if legacy:
                    x = x - self.x_offset
                    y = y - self.y_offset
                if x in range(8) and y in range(8):
                    try:
                        self._grid_value.subject.send_value(
                            x, y, self._colors[value], True)
                    except:
                        pass

    def set_device_selector_matrix(self, matrix):
        self._device_selector.set_matrix(matrix)

    @listens('value')
    def _grid_value(self, value, x, y, *a, **k):
        #self.log_message('_base_grid_value ' + str(x) + str(y) + str(value))
        if self.active_mod():
            if self.active_mod().legacy:
                x += self.x_offset
                y += self.y_offset
            self._active_mod.send('grid', x, y, value)

    @listens('value')
    def _shift_value(self, value, *a, **k):
        self._is_shifted = not value is 0
        mod = self.active_mod()
        if mod:
            mod.send('shift', value)
        if self._is_shifted:
            self.shift_mode.enter_mode()
            if mod and mod.legacy:
                self.legacy_shift_mode.enter_mode()
        else:
            self.legacy_shift_mode.leave_mode()
            self.shift_mode.leave_mode()
        self.update()

    def set_mod_button(self, button):
        self._mod_button = button

    def update(self, *a, **k):
        mod = self.active_mod()
        if self.is_enabled():
            if not mod is None:
                mod.restore()
            else:
                if not self._grid_value.subject is None:
                    self._grid_value.subject.reset()
                if not self._keys_value.subject is None:
                    self._keys_value.subject.reset()
            self._alt_value.subject and self._alt_value.subject.send_value(
                2 + int(self.is_alted()) * 7, True)
            if self._on_lock_value.subject:
                self._on_lock_value.subject.send_value(
                    1 + (int(self.is_locked()) * 4), True)
            else:
                self._mod_button and self._mod_button.send_value(
                    7 + (not self.active_mod() is None) * 7, True)

        else:
            self._mod_button and self._mod_button.send_value(
                (not self.active_mod() is None) * 3, True)
コード例 #29
0
ファイル: Cntrlr.py プロジェクト: amuntner/m4m7
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
コード例 #30
0
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 = u'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(u'automation', [
            self.automation, self._mode_selector,
            partial(self._set_envelope_view_visible, True),
            partial(show_clip_view, self.application)
        ])
        self._settings_modes.add_mode(u'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 = u'note_settings'
        self.__on_selected_setting_mode_changed.subject = self._settings_modes
        self.add_mode(u'disabled', [])
        self.add_mode(u'about_to_show', [
            AddLayerMode(self, initial_encoder_layer),
            (self._show_settings_task.restart, self._show_settings_task.kill)
        ])
        self.add_mode(u'enabled', [
            DetailViewRestorerMode(self.application),
            AddLayerMode(self, encoder_layer), self._settings_modes
        ])
        self.selected_mode = u'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

    automation_layer = forward_property(u'automation')(u'layer')
    mode_selector_layer = forward_property(u'_mode_selector')(u'layer')
    selected_setting = forward_property(u'_settings_modes')(u'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)

    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(u'selected_mode')
    def __on_selected_setting_mode_changed(self, mode):
        if mode == u'automation':
            self.automation.selected_time = self._active_note_regions()

    def update_view_state_based_on_selected_setting(self, setting):
        if self.selected_mode == u'enabled' and self.is_touched or setting is None:
            self._set_settings_view_enabled(False)
        elif self._is_step_held():
            if self.selected_setting == u'automation' and self.automation.can_automate_parameters or self.selected_setting == u'note_settings':
                self._show_settings()

    @listens(u'full_velocity')
    def __on_full_velocity_changed(self):
        for editor in self._editors:
            editor.set_full_velocity()

    @listens(u'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 == u'automation' else should_show_view
        if really_show_view:
            if self.selected_mode == u'disabled':
                self.selected_mode = u'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(u'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)

    @listens_group(u'modify_all_notes')
    def __on_modify_all_notes_changed(self, editor):
        self.selected_mode = u'about_to_show' if editor.modify_all_notes_enabled else u'disabled'

    @listens_group(u'notes_changed')
    def _on_notes_changed(self, editor):
        self._update_infos_task.restart()

    @listens(u'detail_clip')
    def _on_detail_clip_changed(self):
        self.automation.clip = self.song.view.detail_clip if self.is_enabled(
        ) else None

    @listens(u'selected_track')
    def _on_selected_track_changed(self):
        self.selected_mode = u'disabled'

    @initial_encoders.touched
    def initial_encoders(self, encoder):
        if self.selected_mode == u'about_to_show':
            self._show_settings()

    @initial_encoders.value
    def initial_encoders(self, encoder, value):
        if self.selected_mode == u'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 != u'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(
                u'Tweak to add note' if not self._is_edit_all_notes_active()
                and not min_max_values else u'')
コード例 #31
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)
コード例 #32
0
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()
コード例 #33
0
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
コード例 #34
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()
コード例 #35
0
class OhmModHandler(ModHandler):


	def __init__(self, *a, **k):
		super(OhmModHandler, self).__init__(*a, **k)
		self._shift_mode = ModesComponent()
		self._color_type = 'RGB'
		self._shift_mode.add_mode('shift', tuple([self._enable_shift, self._disable_shift]), behaviour = CancellableBehaviourWithRelease())
		self.nav_box = self.register_component(NavigationBox(self, 16, 16, 8, 8, self.set_offset))
		self._mod_button = None
	

	def _enable_shift(self):
		self._shift_value(1)
	

	def _disable_shift(self):
		self._shift_value(0)
	

	def set_shift_button(self, button):
		self._shift_mode.shift_button.set_control_element(button)
	

	def set_nav_matrix(self, matrix):
		self.nav_box.set_matrix(matrix)
	

	def _receive_grid(self, x, y, value, *a, **k):
		#self._receive_grid(x, y, value, *a, **k)
		legacy = self.active_mod().legacy
		if self._active_mod:
			if not self._grid_value.subject is None:
				if legacy:
					x = x - self.x_offset 
					y = y - self.y_offset 
				if x in range(8) and y in range(8):
					try:
						self._grid_value.subject.send_value(x, y, self._colors[value], True)
					except:
						pass
	

	def set_device_selector_matrix(self, matrix):
		self._device_selector.set_matrix(matrix)
	


	@listens('value')
	def _grid_value(self, value, x, y, *a, **k):
		#self.log_message('_base_grid_value ' + str(x) + str(y) + str(value))
		if self.active_mod():
			if self.active_mod().legacy:
				x += self.x_offset
				y += self.y_offset
			self._active_mod.send('grid', x, y, value)
	

	@listens('value')
	def _shift_value(self, value, *a, **k):
		self._is_shifted = not value is 0
		mod = self.active_mod()
		if mod:
			mod.send('shift', value)
		if self._is_shifted:
			self.shift_mode.enter_mode()
			if mod and mod.legacy:
				self.legacy_shift_mode.enter_mode()
		else:
			self.legacy_shift_mode.leave_mode()
			self.shift_mode.leave_mode()
		self.update()
	

	def set_mod_button(self, button):
		self._mod_button = button
	

	def update(self, *a, **k): 
		mod = self.active_mod()
		if self.is_enabled():
			if not mod is None:
				mod.restore()
			else:
				if not self._grid_value.subject is None:
					self._grid_value.subject.reset()
				if not self._keys_value.subject is None:
					self._keys_value.subject.reset()
			self._alt_value.subject and self._alt_value.subject.send_value(2 + int(self.is_alted())*7, True)
			if self._on_lock_value.subject:
				self._on_lock_value.subject.send_value(1 + (int(self.is_locked())*4), True)
			else:
				self._mod_button and self._mod_button.send_value(7 + (not self.active_mod() is None)*7, True)
			
		else:
			self._mod_button and self._mod_button.send_value((not self.active_mod() is None)*3, True)
コード例 #36
0
ファイル: OhmModes.py プロジェクト: aumhaa/m4m7
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)