def _ffwd_value(self, value): if self._shift_pressed: self.song().current_song_time = self.song().last_event_time else: TransportComponent._ffwd_value(self, value)
def _rwd_value(self, value): if self._shift_pressed: self.song().current_song_time = 0.0 else: TransportComponent._rwd_value(self, value)
def __init__(self): self._shift_button = None self._shift_pressed = False TransportComponent.__init__(self)
def disconnect(self): if self._shift_button != None: self._shift_button.remove_value_listener(self._shift_value) self._shift_button = None TransportComponent.disconnect(self)
class Launchkey_MK2(OptimizedControlSurface): identity_request_delay = 0.5 def __init__(self, c_instance, *a, **k): (super(Launchkey_MK2, self).__init__)(a, c_instance=c_instance, **k) self._is_25_key_model = False self._is_in_control_on = True self._identity_response_pending = False with self.component_guard(): self._skin = make_skin() with inject(skin=(const(self._skin))).everywhere(): self._create_controls() self._request_task = self._tasks.add( Task.sequence(Task.wait(self.identity_request_delay), Task.run(self._send_identity_request))) self._request_task.kill() def _create_controls(self): self._encoders = ButtonMatrixElement(rows=[[ make_encoder(identifier, name=('Encoder_%d' % (index, ))) for index, identifier in enumerate(range(21, 29)) ]]) self._top_pad_row = ButtonMatrixElement(rows=[[ make_button(identifier, name=('Pad_0_%d' % (index, ))) for index, identifier in enumerate(range(96, 104)) ]]) self._bottom_pad_row_raw = [ make_button(identifier, name=('Pad_1_%d' % (index, ))) for index, identifier in enumerate(range(112, 120)) ] self._bottom_pad_row = ButtonMatrixElement( rows=[self._bottom_pad_row_raw]) self._top_launch_button = make_button(104, name='Scene_Launch_Button') self._bottom_launch_button = make_button(120, name='Stop_All_Clips_Button') self._scene_up_button = make_button(112, MIDI_CC_TYPE, name='Scene_Up_Button') self._scene_down_button = make_button(113, MIDI_CC_TYPE, name='Scene_Down_Button') self._stop_button = make_button(114, MIDI_CC_TYPE, name='Stop_Button') self._play_button = make_button(115, MIDI_CC_TYPE, name='Play_Button') self._loop_button = make_button(116, MIDI_CC_TYPE, name='Loop_Button') self._record_button = make_button(117, MIDI_CC_TYPE, name='Record_Button') self._sliders = ButtonMatrixElement(rows=[[ make_slider(identifier, name=('Slider_%d' % (index, ))) for index, identifier in enumerate(range(41, 49)) ]]) self._master_slider = make_slider(7, name='Master_Slider') self._25_key_slider = make_slider(7, name='Slider', channel=0) self._mute_buttons_raw = [ make_button(identifier, MIDI_CC_TYPE, name=('Mute_Button_%d' % (index, ))) for index, identifier in enumerate(range(51, 59)) ] self._mute_buttons = ButtonMatrixElement(rows=[self._mute_buttons_raw]) self._master_button = make_button(59, MIDI_CC_TYPE, name='Master_Button') self._track_left_button = make_button(102, MIDI_CC_TYPE, name='Track_Left_Button') self._track_right_button = make_button(103, MIDI_CC_TYPE, name='Track_Right_Button') self._device_mode_button = self._bottom_pad_row_raw[0] self._pan_mode_button = self._bottom_pad_row_raw[1] self._send_mode_buttons = dict() for index in range(consts.MAX_SENDS): setattr(self, '_send_%d_button' % (index, ), self._bottom_pad_row_raw[(index + 2)]) self._send_mode_buttons['send_%d_mode_button' % (index, )] = getattr( self, '_send_%d_button' % (index, )) self._extended_mode_button = make_button( 12, name='Dummy_Extended_Mode_Button') self._extended_mode_button.add_value_listener(nop) self._encoder_incontrol_button = make_button( 13, is_momentary=False, name='Encoder_InControl_Button') self._encoder_incontrol_button.add_value_listener(nop) self._slider_incontrol_button = make_button( 14, is_momentary=False, name='Fader_InControl_Button') self._slider_incontrol_button.add_value_listener(nop) self._pad_incontrol_button = make_button(15, is_momentary=False, name='Pad_InControl_Button') self._pad_incontrol_button.add_value_listener(self._update_pads) self._encoder_incontrol_button2 = make_button( 16, name='Encoder_InControl_Button') self._pad_in_control_status_button = make_button( 11, name='Dummy_InControl_Button') def _create_session(self): self._session = SessionComponent( name='Session', is_enabled=False, num_tracks=(self._top_pad_row.width()), num_scenes=(self._top_pad_row.height()), enable_skinning=True, layer=Layer(clip_launch_buttons=(self._top_pad_row), scene_launch_buttons=ButtonMatrixElement( rows=[[self._top_launch_button]]), stop_track_clip_buttons=(self._bottom_pad_row), stop_all_clips_button=(self._bottom_launch_button))) self._session.set_rgb_mode(LIVE_COLORS_TO_MIDI_VALUES, RGB_COLOR_TABLE) self._session.set_mixer(self._mixer) self._session.set_enabled(True) def _setup_navigation(self): self._session_navigation = SessionNavigationComponent( is_enabled=False, name='Session_Navigation', layer=Layer(next_track_button=(self._track_right_button), prev_track_button=(self._track_left_button), next_scene_button=(self._scene_down_button), prev_scene_button=(self._scene_up_button))) self._session_navigation.set_enabled(True) def _create_transport(self): self._transport = TransportComponent( is_enabled=False, name='Transport', layer=Layer(play_button=(self._play_button), stop_button=(self._stop_button), loop_button=(self._loop_button), record_button=(self._record_button))) self._transport.set_enabled(True) def _create_mixer(self): mixer_volume_layer = None if self._is_25_key_model: mixer_volume_layer = Layer(volume_control=(self._25_key_slider)) else: mixer_volume_layer = Layer(volume_controls=(self._sliders)) self._mixer = MixerComponent(is_enabled=False, name='Mixer', num_tracks=(self._sliders.width()), layer=mixer_volume_layer) if not self._is_25_key_model: self._mixer.master_strip().layer = Layer( volume_control=(self._master_slider)) self._mixer.set_enabled(True) self._mute_button_modes = ModesComponent() mute_mode = AddLayerMode(self._mixer, Layer(mute_buttons=(self._mute_buttons))) solo_mode = AddLayerMode(self._mixer, Layer(solo_buttons=(self._mute_buttons))) self._mute_button_modes.add_mode('mute_mode', mute_mode) self._mute_button_modes.add_mode('solo_mode', solo_mode, behaviour=(CancellableBehaviour())) self._mute_button_modes.layer = Layer( solo_mode_button=(self._master_button)) self._mute_button_modes.selected_mode = 'mute_mode' self._mute_button_modes.set_enabled(True) def _create_device(self): self._device = DeviceComponent( name='Device', is_enabled=False, device_selection_follows_track_selection=True) self.set_device_component(self._device) self._device.set_enabled(True) def _create_background(self): self._background = BackgroundComponent(name='BackgroundComponent') def _create_encoder_modes(self): self._encoder_modes = DisablingModesComponent() self._encoder_modes.default_behaviour = mixin(SkinableBehaviourMixin, ImmediateBehaviour)() device_mode = LayerMode( self._device, Layer(parameter_controls=(self._encoders), bank_buttons=(self._top_pad_row))) pan_mode = AddLayerMode(self._mixer, Layer(pan_controls=(self._encoders))) sends_mode = AddLayerMode(self._mixer, Layer(send_controls=(self._encoders))) background_mode = LayerMode(self._background, Layer(bank_buttons=(self._top_pad_row))) self._encoder_modes.add_mode('device_mode', device_mode, is_enabled=True) self._encoder_modes.add_mode('pan_mode', [pan_mode, background_mode], is_enabled=True) for index in range(6): self._encoder_modes.add_mode(('send_%d_mode' % (index, )), [ sends_mode, partial(self._set_send_index, index), background_mode ], is_enabled=False) self._encoder_modes.selected_mode = 'device_mode' self._encoder_modes.set_enabled(True) def _create_mode_selector(self): self._mode_selector = ModesComponent() mode_selection = LayerMode( self._encoder_modes, Layer(device_mode_button=self._device_mode_button, pan_mode_button=self._pan_mode_button, **self._send_mode_buttons)) device_navigation = AddLayerMode( self._device, Layer(device_nav_left_button=(self._track_left_button), device_nav_right_button=(self._track_right_button))) self._mode_selector.add_mode('mode_selection', [ partial(self._toggle_in_control, True), mode_selection, device_navigation ], behaviour=(MomentaryBehaviour())) session_control = AddLayerMode( self._session, Layer(clip_launch_buttons=(self._top_pad_row))) self._mode_selector.add_mode( 'session_mode', [partial(self._toggle_in_control, False), session_control]) self._mode_selector.layer = Layer( mode_selection_button=(self._encoder_incontrol_button2)) def _create_in_control_status_listener(self): self._in_control_status = InControlStatusComponent( set_is_in_control_on=(self._set_is_in_control_on), is_enabled=False, layer=Layer( in_control_status_button=(self._pad_in_control_status_button))) self._in_control_status.set_enabled(True) @subject_slot('value') def _update_pads(self, value): if value: self.update() @subject_slot('return_tracks') def _on_return_tracks_changed(self): num_sends = self._mixer.num_sends for index in range(6): self._encoder_modes.set_mode_enabled( 'send_%d_mode' % (index, ), True if index < num_sends else False) def _set_send_index(self, index): self._mixer.send_index = index def _set_is_in_control_on(self, value): self._is_in_control_on = value def _toggle_in_control(self, value): if not self._is_in_control_on: self._send_midi(consts.DRUM_IN_CONTROL_ON_MESSAGE if value else consts.DRUM_IN_CONTROL_OFF_MESSAGE) def port_settings_changed(self): self._disconnect_and_unregister_all_components() self._request_task.restart() def handle_sysex(self, midi_bytes): if self._is_identity_response(midi_bytes): product_id_bytes = self._extract_product_id_bytes(midi_bytes) if self._is_identity_response_valid(product_id_bytes): self._set_model_type(product_id_bytes) self._request_task.kill() if self._identity_response_pending: self.on_identified() self._identity_response_pending = False else: self.log_message( 'MIDI device responded with wrong product id (%s).' % (str(product_id_bytes), )) else: super(Launchkey_MK2, self).handle_sysex(midi_bytes) def _extract_product_id_bytes(self, midi_bytes): return midi_bytes[5:] def _is_identity_response(self, midi_bytes): return midi_bytes[3:5] == (6, 2) def _is_identity_response_valid(self, product_id_bytes): return product_id_bytes[: 3] == consts.PRODUCT_ID_BYTE_PREFIX and product_id_bytes[ 3] in consts.PRODUCT_ID_BYTES def _set_model_type(self, product_id_bytes): self._is_25_key_model = product_id_bytes[ 3] == consts.LAUNCHKEY_25_ID_BYTE def _send_identity_request(self): self._identity_response_pending = True self._send_midi(consts.IDENTITY_REQUEST) def on_identified(self): self._extended_mode_button.turn_on() with self.component_guard(): self._create_mixer() self._create_session() self._setup_navigation() self._create_transport() self._create_device() self._create_background() self._create_encoder_modes() self._create_mode_selector() self._create_in_control_status_listener() self._on_return_tracks_changed.subject = self.song() self._on_return_tracks_changed() self._mode_selector.selected_mode = 'session_mode' self.update() def disconnect(self): self._extended_mode_button.turn_off() super(Launchkey_MK2, self).disconnect()
class FocusControl(ControlSurface): controlled_track = None def __init__(self, c_instance): super().__init__(c_instance) self.song().add_is_playing_listener( self._FocusControl__update_play_button_led) register_sender(self) self._active = False self._tracks = [] self.rewind_button_down = False self.forward_button_down = False with self.component_guard(): self._set_suppress_rebuild_requests(True) self._suppress_send_midi = True device = SimpleDeviceComponent() self.set_device_component(device) self._on_selected_track_changed() self.set_up_controls() self.request_rebuild_midi_map() self._set_suppress_rebuild_requests(False) self._active = True self._suppress_send_midi = False self.transport = TransportComponent() self.transport.set_play_button( ButtonElement(False, MIDI_NOTE_TYPE, 0, SID_TRANSPORT_PLAY)) self.transport.set_record_button( ButtonElement(False, MIDI_NOTE_TYPE, 0, SID_TRANSPORT_RECORD)) self.transport.set_seek_buttons( ButtonElement(True, MIDI_NOTE_TYPE, 0, SID_TRANSPORT_FAST_FORWARD), ButtonElement(True, MIDI_NOTE_TYPE, 0, SID_TRANSPORT_REWIND)) self.transport.set_loop_button( ButtonElement(False, MIDI_NOTE_TYPE, 0, SID_TRANSPORT_LOOP)) self._assign_tracks() ctrack = self.get_controlled_track() if ctrack: track = ctrack[0] instr = ctrack[1] self.controlled_track = track index = list(self.song().tracks).index(track) self.update_status_midi(index, track, instr, 1) self.refresh_state() def refresh_state(self): self._FocusControl__update_play_button_led() def receive_midi(self, midi_bytes): if midi_bytes[0] & 240 == MIDI_NOTE_ON_STATUS or midi_bytes[ 0] & 240 == MIDI_NOTE_OFF_STATUS: note = midi_bytes[1] value = BUTTON_PRESSED if midi_bytes[2] > 0 else BUTTON_RELEASED if note in transport_control_switch_ids: self.handle_transport_switch_ids(note, value) super().receive_midi(midi_bytes) def handle_transport_switch_ids(self, switch_id, value): if switch_id == SID_TRANSPORT_REWIND: if value == BUTTON_PRESSED: self.rewind_button_down = True else: if value == BUTTON_RELEASED: self.rewind_button_down = False self._FocusControl__update_forward_rewind_leds() else: if switch_id == SID_TRANSPORT_FAST_FORWARD: if value == BUTTON_PRESSED: self.forward_button_down = True else: if value == BUTTON_RELEASED: self.forward_button_down = False self._FocusControl__update_forward_rewind_leds() else: if switch_id == SID_TRANSPORT_STOP: if value == BUTTON_PRESSED: self._FocusControl__stop_song() def __stop_song(self): self.song().stop_playing() self._FocusControl__update_play_button_led() def __update_play_button_led(self): if self.song().is_playing: self._send_midi( (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_PLAY, BUTTON_STATE_ON)) self._send_midi( (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_STOP, BUTTON_STATE_OFF)) else: self._send_midi( (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_PLAY, BUTTON_STATE_OFF)) self._send_midi( (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_STOP, BUTTON_STATE_ON)) def __update_forward_rewind_leds(self): if self.forward_button_down: self._send_midi((MIDI_NOTE_ON_STATUS, SID_TRANSPORT_FAST_FORWARD, BUTTON_STATE_ON)) else: self._send_midi((MIDI_NOTE_ON_STATUS, SID_TRANSPORT_FAST_FORWARD, BUTTON_STATE_OFF)) if self.rewind_button_down: self._send_midi( (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_REWIND, BUTTON_STATE_ON)) else: self._send_midi( (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_REWIND, BUTTON_STATE_OFF)) def set_up_controls(self): is_momentary = True self.left_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, SID_NAV_LEFT) self.right_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, SID_NAV_RIGHT) self._do_left.subject = self.left_button self._do_right.subject = self.right_button self.stop_button = ButtonElement(False, MIDI_NOTE_TYPE, 0, SID_TRANSPORT_STOP) self._do_stop.subject = self.stop_button @subject_slot('value') def _do_stop(self, value): self._FocusControl__stop_song() @subject_slot('value') def _do_left(self, value): assert value in range(128) if value != 0: self.navigate_midi_track(-1) @subject_slot('value') def _do_right(self, value): assert value in range(128) if value != 0: self.navigate_midi_track(1) def navigate_midi_track(self, direction): tracks = self.song().tracks seltrack = self.song().view.selected_track index = vindexof(tracks, seltrack) nxttrack = self.get_next_track(direction, index, tracks) if nxttrack: self.song().view.selected_track = nxttrack arm_exclusive(self.song(), nxttrack) def get_next_track(self, direction, index, tracks): pos = index if pos is None: pos = len(tracks) pos = pos + direction while 0 <= pos < len(tracks): track = tracks[pos] if track.can_be_armed: return track pos = pos + direction def get_next_midi_track(self, direction, index, tracks): pos = index if pos is None: pos = len(tracks) pos = pos + direction while 0 <= pos < len(tracks): track = tracks[pos] if track.can_be_armed: if track.has_midi_input: return track pos = pos + direction def get_controlled_track(self): armed_tracks = [] tracks = self.song().tracks for track in tracks: if track.can_be_armed and track.arm: armed_tracks.append(track) if len(armed_tracks) == 1: return (armed_tracks[0], self.find_instrument_list(armed_tracks[0].devices)) if len(armed_tracks) > 1: instr = self.find_instrument_ni(armed_tracks) if instr: return instr return self.find_instrument_any(armed_tracks) def find_instrument_ni(self, tracks): for track in tracks: instr = self.find_instrument_list(track.devices) if instr and instr[1] is not None: return (track, instr) def find_instrument_any(self, tracks): for track in tracks: instr = self.find_instrument_list(track.devices) if instr: return (track, instr) def _assign_tracks(self): tracks = self.song().tracks for track in self._tracks: track.release() self._tracks = [] for index in range(len(tracks)): self._tracks.append(TrackElement(index, tracks[index], self)) def activate_track(self, index, track): self.controlled_track = track instr = self.find_instrument_list(track.devices) self.update_status_midi(index, track, instr, 1) def deactivate_track(self, index, track): pass def devices_changed(self, index, track): instr = self.find_instrument_list(track.devices) self.update_status_midi(index, track, instr, 1) def _on_track_list_changed(self): super()._on_track_list_changed() self._assign_tracks() ctrack = self.get_controlled_track() if ctrack: track = ctrack[0] instr = ctrack[1] if track != self.controlled_track: self.controlled_track = track index = list(self.song().tracks).index(track) elif self.controlled_track: self.controlled_track = None def _on_selected_track_changed(self): super()._on_selected_track_changed() self.set_controlled_track(self.song().view.selected_track) def broadcast(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if not s: debug_out(' Could Not open Socket ') else: try: s.connect(('localhost', 60090)) s.sendall('Hello, world'.encode('utf-8')) s.close() except ConnectionError: debug_out(' No Server ') @subject_slot('devices') def _on_devices_changed(self): self.scan_devices() def find_instrument_list(self, devicelist): for device in devicelist: instr = self.find_instrument(device) if instr: return instr def find_in_chain(self, chain): for device in chain.devices: instr = self.find_instrument(device) if instr: return instr def find_instrument(self, device): if device.type == 1: if device.can_have_chains: chains = device.chains for chain in chains: instr = self.find_in_chain(chain) if instr: return instr else: if device.class_name == PLUGIN_CLASS_NAME_VST or device.class_name == PLUGIN_CLASS_NAME_AU: if device.class_display_name.startswith(PLUGIN_PREFIX): parms = device.parameters if parms: if len(parms) > 1: pn = parms[1].name pnLen = len(pn) if pn.startswith(PARAM_PREFIX): return (str(device.class_display_name), str(pn[4:pnLen])) return (device.class_display_name, None) def scan_chain(self, chain): for device in chain.devices: self.scan_device(device) def scan_device(self, device): if device.class_name == 'PluginDevice' and device.class_display_name == 'FocusTester1': parms = device.parameters else: if device.can_have_chains: chains = device.chains for chain in chains: self.scan_chain(chain) def update_status_midi(self, index, track, instrument, value): msgsysex = [240, 0, 0, 102, 20, 18, 0] tr_name = track.name for c in tr_name: msgsysex.append(ord(c)) msgsysex.append(25) ind_str = str(index) for c in ind_str: msgsysex.append(ord(c)) if instrument is not None: msgsysex.append(25) for c in instrument[0]: msgsysex.append(ord(c)) if instrument[1] is not None: msgsysex.append(25) for c in instrument[1]: msgsysex.append(ord(c)) msgsysex.append(247) self._send_midi(tuple(msgsysex)) def send_to_display(self, text, grid=0): if len(text) > 28: text = text[:27] msgsysex = [240, 0, 0, 102, 23, 18, min(grid, 3) * 28] filled = text.ljust(28) for c in filled: msgsysex.append(ord(c)) msgsysex.append(247) self._send_midi(tuple(msgsysex)) def scan_devices(self): song = self.song() for track in song.tracks: for device in track.devices: self.scan_device(device) def disconnect(self): self._active = False self._suppress_send_midi = True self.song().remove_is_playing_listener( self._FocusControl__update_play_button_led) super().disconnect()
class Roland_A_PRO(ControlSurface): def __init__(self, *a, **k): (super(Roland_A_PRO, self).__init__)(*a, **k) with self.component_guard(): self._create_controls() self._create_transport() self._create_mixer() self._create_device() self._create_drums() self._create_modes() def _create_controls(self): self._encoders = ButtonMatrixElement(rows=[ [EncoderElement(MIDI_CC_TYPE, 0, identifier, (Live.MidiMap.MapMode.absolute), name=('Encoder_%d' % index)) for index, identifier in enumerate(ENCODER_IDS)]]) self._master_encoder = EncoderElement(MIDI_CC_TYPE, 0, 10, (Live.MidiMap.MapMode.absolute), name='Master_Encoder') self._sliders = ButtonMatrixElement(rows=[ [SliderElement(MIDI_CC_TYPE, 0, identifier, name=('Slider_%d' % index)) for index, identifier in enumerate(SLIDER_IDS)]]) self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 7, name='Master_Slider') self._play_button = ButtonElement(True, MIDI_CC_TYPE, 0, 26) self._stop_button = ButtonElement(True, MIDI_CC_TYPE, 0, 25) self._record_button = ButtonElement(True, MIDI_CC_TYPE, 0, 28) self._forward_button = ButtonElement(True, MIDI_CC_TYPE, 0, 24) self._backward_button = ButtonElement(True, MIDI_CC_TYPE, 0, 21) self._ff_button = ButtonElement(True, MIDI_CC_TYPE, 0, 23) self._rw_button = ButtonElement(True, MIDI_CC_TYPE, 0, 22) self._device_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 80) self._pan_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 81) self._send_a_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 82) self._send_b_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 83) self._pads = ButtonMatrixElement(rows=[[ButtonElement(True, MIDI_NOTE_TYPE, 0, identifier) for identifier in row] for row in PAD_ROWS]) def _create_transport(self): self._transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer(play_button=(self._play_button), stop_button=(self._stop_button), record_button=(self._record_button))) self._transport.set_enabled(True) def _create_mixer(self): mixer_size = self._sliders.width() self._mixer = MixerComponent(mixer_size, name='Mixer', is_enabled=False, layer=Layer(volume_controls=(self._sliders), prehear_volume_control=(self._master_encoder))) self._mixer.master_strip().layer = Layer(volume_control=(self._master_slider)) self._mixer.set_enabled(True) def _create_device(self): self._device = DeviceComponent(device_selection_follows_track_selection=True) self._device_navigation = DeviceNavigationComponent() self._device.set_enabled(True) self._device_navigation.set_enabled(True) self.set_device_component(self._device) def _create_drums(self): self._drums = DrumRackComponent(name='Drum_Rack', is_enabled=False, layer=Layer(pads=(self._pads))) self._drums.set_enabled(True) def _create_modes(self): self._encoder_modes = ModesComponent() device_layer_mode = LayerMode(self._device, Layer(parameter_controls=(self._encoders))) device_navigation_layer_mode = LayerMode(self._device_navigation, Layer(device_nav_right_button=(self._forward_button), device_nav_left_button=(self._backward_button))) self._encoder_modes.add_mode('device_mode', [device_layer_mode, device_navigation_layer_mode]) self._encoder_modes.add_mode('pan_mode', AddLayerMode(self._mixer, Layer(pan_controls=(self._encoders), bank_up_button=(self._forward_button), bank_down_button=(self._backward_button), track_up_button=(self._ff_button), track_down_button=(self._rw_button)))) send_layer_mode = AddLayerMode(self._mixer, Layer(send_controls=(self._encoders), bank_up_button=(self._forward_button), bank_down_button=(self._backward_button), track_up_button=(self._ff_button), track_down_button=(self._rw_button))) self._encoder_modes.add_mode('send_a_mode', [send_layer_mode, partial(self._set_send_index, 0)]) self._encoder_modes.add_mode('send_b_mode', [send_layer_mode, partial(self._set_send_index, 1)]) self._encoder_modes.layer = Layer(device_mode_button=(self._device_mode_button), pan_mode_button=(self._pan_mode_button), send_a_mode_button=(self._send_a_mode_button), send_b_mode_button=(self._send_b_mode_button)) self._encoder_modes.selected_mode = 'device_mode' self._encoder_modes.set_enabled(True) def _set_send_index(self, index): self._mixer.send_index = index
def _setup_transport(self): is_momentary = True transport = TransportComponent() studiotransport = MaschineTransport() playButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 108) stopButton = StateButton(not is_momentary, MIDI_CC_TYPE, 0, 110) recordButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 109) overdubButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 107) metrononmeButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 104) eventRecButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 98) playButton.name = 'Play' stopButton.name = 'Stop' recordButton.name = 'Record' overdubButton.name = 'Overdub' metrononmeButton.name = 'Metronome' transport.set_play_button(playButton) transport.set_stop_button(stopButton) transport.set_record_button(recordButton) transport.set_overdub_button(overdubButton) transport.set_metronome_button(metrononmeButton) studiotransport.set_session_auto_button(eventRecButton) studiotransport.set_arrangement_overdub_button( StateButton(is_momentary, MIDI_CC_TYPE, 0, 106)) studiotransport.set_back_arrange_button( StateButton(is_momentary, MIDI_CC_TYPE, 0, 105)) transport.set_nudge_buttons( StateButton(is_momentary, MIDI_CC_TYPE, 1, 51), StateButton(is_momentary, MIDI_CC_TYPE, 1, 50)) punchinbutton = ToggleButton(MIDI_CC_TYPE, 1, 52) punchoutbutton = ToggleButton(MIDI_CC_TYPE, 1, 53) punchinbutton.name = 'Punch In' punchoutbutton.name = 'Punch Out' transport.set_punch_buttons(punchinbutton, punchoutbutton) transport.set_loop_button( StateButton(is_momentary, MIDI_CC_TYPE, 1, 54)) self.song_follow_button = ButtonElement(True, MIDI_CC_TYPE, 2, 98) self._do_song_follow.subject = self.song_follow_button self._song_follow_changed.subject = self.song().view self._song_follow_changed() self.transp_ff_button = ButtonElement(True, MIDI_CC_TYPE, 1, 59) self.transp_rw_button = ButtonElement(True, MIDI_CC_TYPE, 1, 58) transport.set_seek_buttons(self.transp_ff_button, self.transp_rw_button) self.xfadeKnob = SliderElement(MIDI_CC_TYPE, 1, 105) self.xfadeKnob.connect_to( self.song().master_track.mixer_device.crossfader) self.master_knob = SliderElement(MIDI_CC_TYPE, 0, 99) self.master_knob.connect_to( self.song().master_track.mixer_device.volume) self.tap_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 88) self._do_tap_tempo.subject = self.tap_button self.cue_add_delete_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 55) self.cue_prev_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 56) self.cue_next_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 57) self._do_toggle_cue.subject = self.cue_add_delete_button self._do_toggle_prev_cue.subject = self.cue_prev_button self._do_toggle_next_cue.subject = self.cue_next_button
def _create_transport(self): self._transport = TransportComponent(name='Transport')
def _create_transport(self): self._transport = TransportComponent(is_enabled=True, name='Transport') self._transport.layer = Layer(play_button=(self._play_button), stop_button=(self._stop_button), record_button=(self._record_button))
def __init__(self): TransportComponent.__init__(self) self._undo_button = None self._redo_button = None self._bts_button = None
class BeatStep(ArturiaControlSurface): def __init__(self, *a, **k): (super(BeatStep, self).__init__)(*a, **k) self._skin = Skin(Colors) with self.component_guard(): self._create_controls() self._create_device() self._create_session() self._create_mixer() self._create_transport() def _create_controls(self): self._device_encoders = ButtonMatrixElement(rows=[[EncoderElement(MIDI_CC_TYPE, 0, identifier, (Live.MidiMap.MapMode.relative_smooth_two_compliment), name=('Encoder_%d_%d' % (column_index, row_index))) for column_index, identifier in enumerate(row)] for row_index, row in enumerate(( ENCODER_MSG_IDS[:4], ENCODER_MSG_IDS[8:12]))]) self._horizontal_scroll_encoder = EncoderElement(MIDI_CC_TYPE, 0, 75, (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Horizontal_Scroll_Encoder') self._vertical_scroll_encoder = EncoderElement(MIDI_CC_TYPE, 0, 72, (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Vertical_Scroll_Encoder') self._volume_encoder = EncoderElement(MIDI_CC_TYPE, 0, 91, (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Volume_Encoder') self._pan_encoder = EncoderElement(MIDI_CC_TYPE, 0, 17, (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Pan_Encoder') self._send_a_encoder = EncoderElement(MIDI_CC_TYPE, 0, 77, (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Send_A_Encoder') self._send_b_encoder = EncoderElement(MIDI_CC_TYPE, 0, 93, (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Send_B_Encoder') self._send_encoders = ButtonMatrixElement(rows=[ [ self._send_a_encoder, self._send_b_encoder]]) self._return_a_encoder = EncoderElement(MIDI_CC_TYPE, 0, 73, (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Return_A_Encoder') self._return_b_encoder = EncoderElement(MIDI_CC_TYPE, 0, 79, (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Return_B_Encoder') self._return_encoders = ButtonMatrixElement(rows=[ [ self._return_a_encoder, self._return_b_encoder]]) self._pads = ButtonMatrixElement(rows=[[ButtonElement(True, MIDI_NOTE_TYPE, PAD_CHANNEL, identifier, name=('Pad_%d_%d' % (col_index, row_index)), skin=(self._skin)) for col_index, identifier in enumerate(row)] for row_index, row in enumerate(PAD_MSG_IDS)]) self._stop_button = ButtonElement(True, MIDI_CC_TYPE, 0, 1, name='Stop_Button') self._play_button = ButtonElement(True, MIDI_CC_TYPE, 0, 2, name='Play_Button') def _create_device(self): self._device = DeviceComponent(name='Device', is_enabled=False, layer=Layer(parameter_controls=(self._device_encoders)), device_selection_follows_track_selection=True) self._device.set_enabled(True) self.set_device_component(self._device) def _create_session(self): self._session = SessionComponent(name='Session', is_enabled=False, num_tracks=(self._pads.width()), num_scenes=(self._pads.height()), enable_skinning=True, layer=Layer(clip_launch_buttons=(self._pads), scene_select_control=(self._vertical_scroll_encoder))) self._session.set_enabled(True) def _create_mixer(self): self._mixer = MixerComponent(name='Mixer', is_enabled=False, num_returns=2, layer=Layer(track_select_encoder=(self._horizontal_scroll_encoder), selected_track_volume_control=(self._volume_encoder), selected_track_pan_control=(self._pan_encoder), selected_track_send_controls=(self._send_encoders), return_volume_controls=(self._return_encoders))) self._mixer.set_enabled(True) def _create_transport(self): self._transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer(stop_button=(self._stop_button), play_button=(self._play_button))) self._transport.set_enabled(True) def _collect_setup_messages(self): for identifier, hardware_id in zip(ENCODER_MSG_IDS, HARDWARE_ENCODER_IDS): self._setup_hardware_encoder(hardware_id, identifier) self._setup_hardware_button(HARDWARE_STOP_BUTTON_ID, 1, msg_type='cc') self._setup_hardware_button(HARDWARE_PLAY_BUTTON_ID, 2, msg_type='cc') for hardware_id, identifier in zip(HARDWARE_PAD_IDS, chain(*PAD_MSG_IDS)): self._setup_hardware_button(hardware_id, identifier, PAD_CHANNEL, msg_type='note')
def _create_transport(self): self._transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer(stop_button=(self._stop_button), play_button=(self._play_button))) self._transport.set_enabled(True)
class Axiom_AIR_25_49_61(ControlSurface): def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._alt_device_component = None with self.component_guard(): self.set_pad_translations(PAD_TRANSLATIONS) self._suggested_input_port = 'HyperControl' self._suggested_output_port = 'HyperControl' self._single_fader_button_modes = None self._has_faders = True self._display_reset_delay = -1 self._hc_byte = HC_BYTE self._waiting_for_first_response = True self._setup_controls() self._setup_displays() self._setup_mixer() self._setup_session() self._setup_transport() self._setup_device() self._setup_modes() self._drum_group_midi_button = None self._drum_group_hyper_button = None for component in self.components: component.set_enabled(False) def disconnect(self): self._scheduled_messages = [] for encoder in self._encoders: encoder.remove_value_listener(self._encoder_value) for fader in self._faders: fader.remove_value_listener(self._fader_value) for fader_button in self._fader_buttons: fader_button.remove_value_listener(self._fader_button_value) self._master_fader.remove_value_listener(self._fader_value) self._master_fader_button.remove_value_listener( self._fader_button_value) self._select_button.remove_value_listener(self._select_button_value) self._identify_button.remove_value_listener(self._identify_value) self._fader_group_midi_button.remove_value_listener( self._midi_button_value) self._fader_group_mix_button.remove_value_listener( self._hyper_button_value) self._fader_group_fx_button.remove_value_listener( self._hyper_button_value) self._encoder_group_midi_button.remove_value_listener( self._midi_button_value) self._encoder_group_mix_button.remove_value_listener( self._hyper_button_value) self._encoder_group_fx_button.remove_value_listener( self._hyper_button_value) if self._drum_group_midi_button != None: self._drum_group_midi_button.remove_value_listener( self._midi_button_value) if self._drum_group_hyper_button != None: self._drum_group_hyper_button.remove_value_listener( self._hyper_button_value) self._alt_device_component = None self._name_display = None self._value_display = None self._bank_display = None self._pad_display = None self._name_display_data_source = None self._value_display_data_source = None self._bank_display_data_source = None self._pad_display_data_source = None self._select_button = None self._left_button = None self._right_button = None self._up_button = None self._down_button = None self._loop_button = None self._ffwd_button = None self._rwd_button = None self._play_button = None self._stop_button = None self._rec_button = None self._master_fader_button = None self._fader_buttons = None self._faders = None self._encoders = None self._drum_pads = None self._identify_button = None self._main_group_hyper_button = None self._main_group_track_button = None self._main_group_fx_button = None self._encoder_group_midi_button = None self._encoder_group_mix_button = None self._encoder_group_fx_button = None self._fader_group_mode_button = None self._fader_group_midi_button = None self._fader_group_mix_button = None self._fader_group_fx_button = None self._drum_group_midi_button = None self._drum_group_roll_button = None self._drum_group_hyper_button = None self._mixer_for_encoders = None self._mixer_for_faders = None self._device_for_encoders = None self._device_for_faders = None self._transport = None self._session = None ControlSurface.disconnect(self) self._send_midi(SYSEX_START + DISABLE_HYPERCONTROL) def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._send_midi, IDENTITY_REQUEST) def handle_sysex(self, midi_bytes): if midi_bytes[0:10] == AXIOM_AIR_RESPONSE: if midi_bytes[12:15] < AXIOM_REV4_RESPONSE: self.schedule_message(1, self._send_midi, SYSEX_START + ENGAGE_HYPERCONTROL) self.schedule_message(2, self._send_midi, SYSEX_START + CLEAR_ALL) self.schedule_message(3, self._name_display.display_message, 'Firmware') self.schedule_message(13, self._name_display.display_message, 'Update') self.schedule_message(23, self._name_display.display_message, 'Required') self.schedule_message(33, self._send_midi, SYSEX_START + DISABLE_HYPERCONTROL) elif midi_bytes[12:15] >= AXIOM_REV4_RESPONSE: if self._waiting_for_first_response == True: self._waiting_for_first_response = False self._has_faders = midi_bytes[10] != 50 self.schedule_message(1, self._send_midi, SYSEX_START + ENGAGE_HYPERCONTROL) self.schedule_message(2, self._send_midi, SYSEX_START + SPECIAL_HYPERCONTROL) self.schedule_message(3, self._complete_setup) else: self._display_reset_delay = 0 elif midi_bytes[0:8] == REQUEST_HYPERCONTROL: self.schedule_message(5, self._send_midi, IDENTITY_REQUEST) def update_display(self): ControlSurface.update_display(self) if self._display_reset_delay >= 0: self._display_reset_delay -= 1 if self._display_reset_delay == -1: self._set_displays_to_default() def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) self._display_reset_delay = 0 def restore_bank(self, bank_index): ControlSurface.restore_bank(self, bank_index) if self._alt_device_component != None: self._alt_device_component.restore_bank(bank_index) def set_appointed_device(self, device): ControlSurface.set_appointed_device(self, device) with self.component_guard(): if self._alt_device_component != None: self._alt_device_component.set_device(device) def set_alt_device_component(self, device_component): self._alt_device_component = device_component def _update_device_selection(self): track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None: if len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) if self._alt_device_component != None: self._alt_device_component.set_device(device_to_select) def _setup_controls(self): self._left_button = create_button(99, 'Left_Button') self._right_button = create_button(100, 'Right_Button') self._up_button = create_button(101, 'Up_Button') self._down_button = create_button(102, 'Down_Button') self._loop_button = create_button(113, 'Loop_Button') self._rwd_button = create_button(114, 'Rwd_Button') self._ffwd_button = create_button(115, 'FFwd_Button') self._stop_button = create_button(116, 'Stop_Button') self._play_button = create_button(117, 'Play_Button') self._rec_button = create_button(118, 'Record_Button') self._select_button = ConfigurableButtonElement( IS_MOMENTARY, MIDI_CC_TYPE, GLOBAL_CHANNEL, 98) self._select_button.name = 'Select_Button' self._select_button.add_value_listener(self._select_button_value) self._main_group_hyper_button = create_configurable_button( 104, 'Fader_Group_HyperControl_Button', 2, 14) self._main_group_track_button = create_configurable_button( 105, 'Main_Group_Track_Button', 2, 11) self._main_group_fx_button = create_configurable_button( 106, 'Main_Group_Inst_FX_Button', 2, 11) self._identify_button = create_configurable_button( 97, 'Identify_Button', 2, 16) self._identify_button.add_value_listener(self._identify_value) self._fader_buttons = [] for index in range(8): self._fader_buttons.append( create_configurable_button(49 + index, 'Fader_Button_%d' % index)) self._fader_buttons[(-1)].add_value_listener( (self._fader_button_value), identify_sender=True) self._faders = [] for index in range(8): self._faders.append(create_slider(33 + index, 'Fader_%d' % index)) self._faders[(-1)].add_value_listener((self._fader_value), identify_sender=True) self._master_fader_button = create_configurable_button( 57, 'Master_Fader_Button') self._master_fader_button.add_value_listener( (self._fader_button_value), identify_sender=True) self._master_fader = create_slider(41, 'Master_Fader') self._master_fader.add_value_listener((self._fader_value), identify_sender=True) self._fader_group_mode_button = create_configurable_button( 61, 'Fader_Group_Mode_Button') self._fader_group_midi_button = create_configurable_button( 60, 'Fader_Group_MIDI_Button') self._fader_group_midi_button.add_value_listener( (self._midi_button_value), identify_sender=True) self._fader_group_mix_button = create_configurable_button( 58, 'Fader_Group_Mix_Button', 0, 1) self._fader_group_mix_button.add_value_listener( (self._hyper_button_value), identify_sender=True) self._fader_group_fx_button = create_configurable_button( 59, 'Fader_Group_Inst_FX_Button', 0, -1) self._fader_group_fx_button.add_value_listener( (self._hyper_button_value), identify_sender=True) self._encoders = [] for index in range(8): self._encoders.append( create_encoder(17 + index, 'Encoder_%d' % index)) self._encoders[(-1)].add_value_listener((self._encoder_value), identify_sender=True) self._encoder_group_midi_button = create_configurable_button( 27, 'Encoder_Group_MIDI_Button', 0, 72) self._encoder_group_midi_button.add_value_listener( (self._midi_button_value), identify_sender=True) self._encoder_group_mix_button = create_configurable_button( 25, 'Encoder_Group_Mix_Button', 0, 72) self._encoder_group_mix_button.add_value_listener( (self._hyper_button_value), identify_sender=True) self._encoder_group_fx_button = create_configurable_button( 26, 'Encoder_Group_Inst_FX_Button', 0, 72) self._encoder_group_fx_button.add_value_listener( (self._hyper_button_value), identify_sender=True) def _setup_drum_pads(self): self._drum_pads = [] num_pads = 12 if self._has_faders else 16 for index in range(8): self._drum_pads.append( create_configurable_button(81 + index, 'Pad_%d' % index, 0, 0, MIDI_CC_TYPE)) for index in range(num_pads - 8): self._drum_pads.append( ConfigurableButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, GLOBAL_CHANNEL - 1, 81 + index, GLOBAL_SEND_CHANNEL, 8, MIDI_CC_TYPE)) self._drum_pads[(-1)].name = 'Pad_' + str(index + 8) self._drum_group_midi_button = create_configurable_button( 91, 'Drum_Group_MIDI_Button', 2, -2) self._drum_group_midi_button.add_value_listener( (self._midi_button_value), identify_sender=True) self._drum_group_roll_button = create_configurable_button( 90, 'Drum_Group_Roll_Button', -1) self._drum_group_hyper_button = create_configurable_button( 89, 'Drum_Group_HyperControl_Button', 2, 2) self._drum_group_hyper_button.add_value_listener( (self._hyper_button_value), identify_sender=True) def _setup_displays(self): self._name_display = PhysicalDisplayElement(12, 1) self._name_display.name = 'Name_Display' self._name_display.set_message_parts(SYSEX_START + (21, ), (0, 247)) self._name_display.set_clear_all_message(CLEAR_NAME) self._name_display_data_source = DisplayDataSource() self._name_display.segment(0).set_data_source( self._name_display_data_source) self._value_display = NumericalDisplayElement(3, 1) self._value_display.name = 'Value_Display' self._value_display.set_message_parts(SYSEX_START + (20, 48), (0, 247)) self._value_display.set_clear_all_message(CLEAR_VALUE) self._value_display_data_source = DisplayDataSource() self._value_display.segment(0).set_data_source( self._value_display_data_source) self._bank_display = NumericalDisplayElement(3, 1) self._bank_display.name = 'Bank_Display' self._bank_display.set_message_parts(SYSEX_START + (19, ), (0, 247)) self._bank_display.set_clear_all_message(CLEAR_BANK) self._bank_display_data_source = DisplayDataSource() self._bank_display.segment(0).set_data_source( self._bank_display_data_source) self._pad_display = NumericalDisplayElement(2, 1) self._pad_display.name = 'Pad_Display' self._pad_display.set_message_parts(SYSEX_START + (18, ), (0, 247)) self._pad_display.set_clear_all_message(CLEAR_PAD) self._pad_display_data_source = DisplayDataSource() self._pad_display.segment(0).set_data_source( self._pad_display_data_source) def _setup_mixer(self): self._mixer_for_encoders = SpecialMixerComponent( self._name_display, self._value_display, 8) self._mixer_for_encoders.name = 'Mixer_for_encoders' self._mixer_for_faders = SpecialMixerComponent(self._name_display, self._value_display, 8) self._mixer_for_faders.name = 'Mixer_for_faders' def _setup_session(self): self._session = SpecialSessionComponent(8, 0) self._session.name = 'Session_Control' self._session.selected_scene().name = 'Selected_Scene' self._session.set_mixer(self._mixer_for_encoders) self._session.set_alt_mixer(self._mixer_for_faders) self._session.add_offset_listener(self._update_bank_value) def _setup_transport(self): self._transport = TransportComponent() self._transport.name = 'Transport' self._transport.set_stop_button(self._stop_button) self._transport.set_play_button(self._play_button) self._transport.set_record_button(self._rec_button) transport_view_modes = TransportViewModeSelector( self._transport, self._session, self._ffwd_button, self._rwd_button, self._loop_button) transport_view_modes.name = 'Transport_View_Modes' def _setup_device(self): self._device_for_encoders = BestBankDeviceComponent( device_selection_follows_track_selection=True) self._device_for_encoders.name = 'Device_Component_for_encoders' self._device_for_faders = BestBankDeviceComponent( device_selection_follows_track_selection=True) self._device_for_faders.name = 'Device_Component_for_faders' self.set_device_component(self._device_for_encoders) self.set_alt_device_component(self._device_for_faders) self._device_nav = DeviceNavComponent() self._device_nav.name = 'Device_Nav_Component' def _setup_modes(self): self._fader_button_modes = FaderButtonModeSelector( self._mixer_for_faders, tuple(self._fader_buttons)) self._fader_button_modes.name = 'Fader_Button_Modes' self._fader_button_modes.set_mode_toggle(self._fader_group_mode_button) self._fader_modes = FaderModeSelector(self._mixer_for_faders, self._device_for_faders, tuple(self._faders), self._fader_button_modes, self._master_fader_button) self._fader_modes.name = 'Fader_Modes' self._fader_modes.set_mode_buttons( (self._fader_group_mix_button, self._fader_group_fx_button)) self._encoder_modes = EncoderModeSelector(self._mixer_for_encoders, self._device_for_encoders, tuple(self._encoders)) self._encoder_modes.name = 'Encoder_Modes' self._encoder_modes.set_mode_buttons( (self._encoder_group_mix_button, self._encoder_group_fx_button)) main_modes = MainModeSelector(self._device_for_encoders, self._device_for_faders, self._session, self._mixer_for_faders, self._device_nav, self._up_button, self._down_button, self._left_button, self._right_button, self._select_button) main_modes.name = 'Main_Modes' main_modes.set_mode_buttons( (self._main_group_track_button, self._main_group_fx_button)) def _setup_master_fader(self): if self._has_faders: self._mixer_for_encoders.master_strip().set_volume_control( self._master_fader) else: self._mixer_for_encoders.selected_strip().set_volume_control( self._master_fader) def _setup_single_fader_button_modes(self): self._single_fader_button_modes = SingleFaderButtonModeSelector( self._mixer_for_encoders, self._fader_group_midi_button) self._single_fader_button_modes.name = 'Single_Fader_Button_Modes' self._single_fader_button_modes.set_mode_toggle( self._fader_group_mode_button) def _complete_setup(self): self._setup_drum_pads() self._set_drum_pads_to_hc() self._setup_master_fader() if not self._has_faders: self._setup_single_fader_button_modes() for control in self.controls: if isinstance(control, InputControlElement): control.clear_send_cache() for component in self.components: component.set_enabled(True) self._fader_group_midi_button.send_value(LED_OFF, True) self._encoder_group_midi_button.send_value(LED_OFF, True) self._main_group_hyper_button.send_value(AMB_FULL, True) self.request_rebuild_midi_map() self._on_selected_track_changed() self.schedule_message(1, self._show_startup_message) def _show_startup_message(self): self._send_midi(SYSEX_START + CLEAR_ALL) self._name_display.display_message('Ableton Live') self._display_reset_delay = INITIAL_DISPLAY_DELAY def _select_button_value(self, value): self._display_reset_delay = STANDARD_DISPLAY_DELAY def _identify_value(self, value): for encoder in self._encoders: encoder.set_identify_mode(value > 0) for fader in self._faders: fader.set_identify_mode(value > 0) self._master_fader.set_identify_mode(value > 0) self._display_reset_delay = 0 self._identify_button.turn_on( ) if value > 0 else self._identify_button.turn_off() def _midi_button_value(self, value, sender): if value > 0: if sender is self._drum_group_midi_button: hc_byte = self._hc_byte ^ PADS if hc_byte != self._hc_byte: self._hc_byte = hc_byte self._drum_group_hyper_button.send_value(LED_OFF, True) self.schedule_message( 1, self._send_midi, SYSEX_START + (32, self._hc_byte, 247)) elif sender is self._encoder_group_midi_button: hc_byte = self._hc_byte ^ ENCODERS if hc_byte != self._hc_byte: self._hc_byte = hc_byte self._encoder_group_mix_button.send_value(LED_OFF, True) self._encoder_group_fx_button.send_value(LED_OFF, True) if self._encoder_modes.mode_index < 3: self._encoder_modes.set_enabled(False) self.schedule_message( 1, self._send_midi, SYSEX_START + (32, self._hc_byte, 247)) elif sender is self._fader_group_midi_button: if self._has_faders: hc_byte = self._hc_byte ^ FADERS if hc_byte != self._hc_byte: self._hc_byte = hc_byte self._fader_group_mix_button.send_value(LED_OFF, True) self._fader_group_fx_button.send_value(LED_OFF, True) self._fader_group_mode_button.send_value(LED_OFF, True) if self._fader_modes.mode_index < 2: self._fader_modes.set_enabled(False) self._fader_button_modes.set_enabled(False) self.schedule_message( 1, self._send_midi, SYSEX_START + (32, self._hc_byte, 247)) else: self._display_reset_delay = STANDARD_DISPLAY_DELAY def _hyper_button_value(self, value, sender): if value > 0: if sender is self._drum_group_hyper_button: if self._hc_byte | PADS != self._hc_byte: self._hc_byte = self._hc_byte | PADS self._send_midi(SYSEX_START + (32, self._hc_byte, 247)) self.schedule_message(1, self._set_drum_pads_to_hc) elif sender is self._encoder_group_fx_button or sender is self._encoder_group_mix_button: if self._hc_byte | ENCODERS != self._hc_byte: self._hc_byte = self._hc_byte | ENCODERS self._send_midi(SYSEX_START + (32, self._hc_byte, 247)) self._encoder_group_midi_button.turn_off() if sender is self._encoder_group_fx_button: self._encoder_modes.set_enabled(True) self._display_reset_delay = 0 return self.schedule_message(1, self._encoder_modes.set_enabled, True) self.schedule_message(1, self._encoder_modes.update) self._display_reset_delay = 2 return else: if sender is self._fader_group_fx_button or ( sender is self._fader_group_mix_button): if self._hc_byte | FADERS != self._hc_byte: self._hc_byte = self._hc_byte | FADERS self._send_midi(SYSEX_START + (32, self._hc_byte, 247)) self._fader_group_midi_button.turn_off() self._fader_button_modes.set_enabled(True) if sender is self._fader_group_fx_button: self._fader_modes.set_enabled(True) self._fader_button_modes.set_enabled(True) self._display_reset_delay = 0 return self.schedule_message(1, self._fader_modes.set_enabled, True) self.schedule_message(1, self._fader_modes.update) self.schedule_message( 1, self._fader_button_modes.set_enabled, True) self.schedule_message(1, self._fader_button_modes.update) self._display_reset_delay = 2 return self._display_reset_delay = 0 def _set_drum_pads_to_hc(self): self._drum_group_midi_button.send_value(LED_OFF, True) self._drum_group_hyper_button.send_value(RED_FULL, True) for index in range(len(self._drum_pads)): self._drum_pads[index].send_value(RED_LOW, True) def _fader_button_value(self, value, sender): self._display_reset_delay = STANDARD_DISPLAY_DELAY def _fader_value(self, value, sender): param = sender.mapped_parameter() if param != None: param_range = param.max - param.min if param.name == 'Track Volume': if sender == self._master_fader: if self._has_faders: name_string = 'Master Vol' else: name_string = self._mixer_for_faders.selected_strip( ).track_name_data_source().display_string() + ' Vol' else: name_string = self._mixer_for_faders.channel_strip( self._faders.index(sender)).track_name_data_source( ).display_string() + ' Vol' else: name_string = param.name value = int( old_div(param.value - param.min, param_range) * 127) value_string = str(value) else: name_string = '<unmapped>' value_string = None self.schedule_message(1, self._set_value_string) self._set_name_string(name_string) self._set_value_string(value_string) def _encoder_value(self, value, sender): param = sender.mapped_parameter() if param != None: param_range = param.max - param.min if param.name == 'Track Volume': name_string = self._mixer_for_encoders.channel_strip( self._encoders.index(sender)).track_name_data_source( ).display_string() + ' Vol' value = int( old_div(param.value - param.min, param_range) * 127) elif param.name == 'Track Panning': name_string = self._mixer_for_encoders.channel_strip( self._encoders.index(sender)).track_name_data_source( ).display_string() + ' Pan' value = int(old_div(param.value, param_range) * 127) if value < 0: name_string += ' L' elif value > 0: name_string += ' R' else: name_string += ' C' else: name_string = param.name value = int( old_div(param.value - param.min, param_range) * 127) value_string = str(value) else: name_string = '<unmapped>' value_string = None self.schedule_message(1, self._set_value_string) self._set_name_string(name_string) self._set_value_string(value_string) def _set_displays_to_default(self): self._name_display.segment(0).set_data_source( self._mixer_for_encoders.selected_strip().track_name_data_source()) self._name_display.update() self._update_bank_value() self._set_value_string(None) self._send_midi(SYSEX_START + LCD_HC_DEFAULT) def _set_name_string(self, name_string): self._name_display.segment(0).set_data_source( self._name_display_data_source) self._name_display_data_source.set_display_string(name_string) self._display_reset_delay = STANDARD_DISPLAY_DELAY def _set_value_string(self, value_string=None): if value_string != None: self._value_display_data_source.set_display_string(value_string) else: self._value_display.reset() def _set_bank_string(self, bank_string=None): if bank_string != None: self._bank_display_data_source.set_display_string(bank_string) else: self._bank_display.reset() def _update_bank_value(self): bank = old_div(self._session.track_offset() + 1, self._session.width()) + 1 self._set_bank_string(str(bank)) def _install_mapping(self, midi_map_handle, control, parameter, feedback_delay, feedback_map): success = False feedback_rule = None if control.message_type() is MIDI_NOTE_TYPE: feedback_rule = Live.MidiMap.NoteFeedbackRule() feedback_rule.note_no = 0 feedback_rule.vel_map = (0, ) elif control.message_type() is MIDI_CC_TYPE: feedback_rule = Live.MidiMap.CCFeedbackRule() feedback_rule.cc_no = 0 feedback_rule.cc_value_map = (0, ) elif control.message_type() is MIDI_PB_TYPE: feedback_rule = Live.MidiMap.PitchBendFeedbackRule() feedback_rule.value_pair_map = feedback_map feedback_rule.channel = control.message_channel() feedback_rule.delay_in_ms = feedback_delay if control.message_type() is MIDI_NOTE_TYPE: success = Live.MidiMap.map_midi_note_with_feedback_map( midi_map_handle, parameter, control.message_channel(), control.message_identifier(), feedback_rule) elif control.message_type() is MIDI_CC_TYPE: success = Live.MidiMap.map_midi_cc_with_feedback_map( midi_map_handle, parameter, control.message_channel(), control.message_identifier(), control.message_map_mode(), feedback_rule, not control.needs_takeover()) elif control.message_type() is MIDI_PB_TYPE: success = Live.MidiMap.map_midi_pitchbend_with_feedback_map( midi_map_handle, parameter, control.message_channel(), feedback_rule, not control.needs_takeover()) return success
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): is_momentary = True self.set_pad_translations(PAD_TRANSLATIONS) self._suggested_input_port = 'HyperControl' self._suggested_output_port = 'HyperControl' self._display_on_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 15, 79) self._waiting_for_first_response = True mixer1 = DisplayingMixerComponent(0) mixer1.set_select_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 111), ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 110)) mixer1.set_mute_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 12)) mixer1.set_solo_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 13)) mixer2 = NotifyingMixerComponent(8) mixer2.set_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 15), ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 14)) mixer2.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, 15, 41)) for index in range(8): mixer2.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, 15, 33 + index)) device = PageableDeviceComponent(device_selection_follows_track_selection=True) self.set_device_component(device) ffwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 115) rwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 114) loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 113) transport = TransportComponent() transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 116)) transport.set_play_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 117)) transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 118)) session = SessionComponent(0, 0) transport_view_modes = TransportViewModeSelector(transport, session, ffwd_button, rwd_button, loop_button) select_button_modes = SelectButtonModeSelector(mixer2, tuple([ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 49 + offset) for offset in range(8)])) select_button_modes.set_mode_toggle(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 57)) self._mixer_encoder_modes = EncoderMixerModeSelector(mixer2) encoders = [] for offset in range(8): encoders.append(PeekableEncoderElement(MIDI_CC_TYPE, 15, 17 + offset, Live.MidiMap.MapMode.relative_smooth_two_compliment)) encoders[(-1)].set_feedback_delay(-1) mixer_or_device = MixerOrDeviceModeSelector(self._mixer_encoder_modes, device, tuple(encoders), tuple([ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 74 + offset) for offset in range(4)])) mixer_or_device.set_mode_toggle(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 109)) mixer_or_device.set_peek_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 78)) self._track_display = PhysicalDisplayElement(8, 1) self._track_display.set_clear_all_message(SYSEX_START + (16, 247)) self._track_display.set_message_parts(SYSEX_START + (17, 1, 0, 0), (247, )) self._track_display.segment(0).set_data_source(mixer1.selected_strip().track_name_data_source()) device_display = PhysicalDisplayElement(8, 1) device_display.set_message_parts(SYSEX_START + (17, 1, 0, 10), (247, )) parameter_display = PhysicalDisplayElement(16, 1) parameter_display.set_message_parts(SYSEX_START + (17, 2, 0, 0), (247, )) select_button_modes.set_mode_display(parameter_display) mixer1.set_display(parameter_display) mixer2.set_bank_display(parameter_display) page_displays = [] for index in range(4): page_displays.append(PhysicalDisplayElement(5, 1)) page_displays[(-1)].set_message_parts(SYSEX_START + (17, 4, index, 0), (247, )) encoder_display = PhysicalDisplayElement(80, 8) encoder_display.set_message_parts(SYSEX_START + (17, 3), (247, )) for index in range(8): pos_id = tuple() if index != 0: pos_id += (0, ) else: if index > 3: pos_id += (index % 4, 13) else: pos_id += (index % 4, 0) encoder_display.segment(index).set_position_identifier(pos_id) mixer_or_device.set_displays(encoder_display, parameter_display, device_display, tuple(page_displays)) for component in self.components: component.set_enabled(False)