def __init__(self, *a, **k): (super(Advance, self).__init__)(*a, **k) with self.component_guard(): encoders = ButtonMatrixElement(rows=[[ make_encoder(index + 22, 'Encoder_%d' % index) for index in range(8) ]]) pads = ButtonMatrixElement(rows=[[ make_button(identifier, 'Pad_%d_%d' % (col, row)) for col, identifier in enumerate(row_ids) ] for row, row_ids in enumerate(PAD_IDS)]) device = DeviceComponent( is_enabled=False, layer=Layer(parameter_controls=encoders), device_selection_follows_track_selection=True) device.set_enabled(True) self.set_device_component(device) drums = DrumRackComponent(is_enabled=False, layer=Layer(pads=pads)) drums.set_enabled(True) play_button = make_button(118, 'Play_Button', MIDI_CC_TYPE, 0) stop_button = make_button(117, 'Stop_Button', MIDI_CC_TYPE, 0) record_button = make_button(119, 'Record_Button', MIDI_CC_TYPE, 0) loop_button = make_button(114, 'Loop_Button', MIDI_CC_TYPE, 0) transport = TransportComponent(is_enabled=False, layer=Layer( play_button=play_button, stop_button=stop_button, record_button=record_button, loop_button=loop_button)) transport.set_enabled(True)
def __init__(self, *a, **k): (super(MPK225, self).__init__)(*a, **k) with self.component_guard(): midimap = MidiMap() drum_rack = DrumRackComponent( name='Drum_Rack', is_enabled=False, layer=Layer(pads=(midimap['Drum_Pads']))) drum_rack.set_enabled(True) transport = TransportComponent( name='Transport', is_enabled=False, layer=Layer(play_button=(midimap['Play']), record_button=(midimap['Record']), stop_button=(midimap['Stop']), seek_forward_button=(midimap['Forward']), seek_backward_button=(midimap['Backward']), loop_button=(midimap['Loop']))) transport.set_enabled(True) device = DeviceComponent( name='Device', is_enabled=False, layer=Layer(parameter_controls=(midimap['Encoders'])), device_selection_follows_track_selection=True) device.set_enabled(True) self.set_device_component(device)
def __init__(self, *a, **k): (super(Alesis_V, self).__init__)(*a, **k) with self.component_guard(): encoders = ButtonMatrixElement(rows=[[ EncoderElement(MIDI_CC_TYPE, 0, (identifier + 20), (Live.MidiMap.MapMode.absolute), name=('Encoder_%d' % identifier)) for identifier in range(4) ]]) device = DeviceComponent( name='Device', is_enabled=False, layer=Layer(parameter_controls=encoders), device_selection_follows_track_selection=True) device.set_enabled(True) self.set_device_component(device)
class LaunchControl(ControlSurface): def __init__(self, c_instance): super(LaunchControl, self).__init__(c_instance) with self.component_guard(): self._init_mixer() self._init_session() self._init_device() self._init_modes() self._refresh_state_task = self._tasks.add( Task.sequence(Task.delay(3), Task.run(self._do_refresh_state))) self._refresh_state_task.kill() self.log_message('Launch Control script loaded') def disconnect(self): super(LaunchControl, self).disconnect() for channel in range(16): self._send_midi((CC_STATUS + channel, 0, 0)) def refresh_state(self): self._refresh_state_task.restart() def _do_refresh_state(self): self._send_current_mode() self._update_hardware() self.schedule_message(3, super(LaunchControl, self).refresh_state) def _update_hardware(self): for channel in range(8, 11): self._send_midi(Sysex.make_automatic_flashing_message(channel)) def _send_current_mode(self): try: self._send_midi(MODE_SYSEX_MAP[self._modes.selected_mode]) except KeyError: pass def _init_mixer(self): make_button = partial(make_launch_control_button, channel=8) make_encoder = partial(make_launch_control_encoder, channel=8) bottom_encoders, top_encoders = make_all_encoders( 'Mixer', make_encoder) pan_volume_layer = Layer( volume_controls=ButtonMatrixElement(rows=[bottom_encoders]), pan_controls=ButtonMatrixElement(rows=[top_encoders])) sends_layer = Layer(sends_controls=ButtonMatrixElement( rows=[bottom_encoders, top_encoders])) modes_layer = Layer(pan_volume_button=(make_button( 114, 'Pan_Volume_Mode_Button')), sends_button=(make_button(115, 'Sends_Mode_Button'))) self._mixer = SpecialMixerComponent(8, modes_layer, pan_volume_layer, sends_layer) self._mixer.set_enabled(False) self._mixer.name = 'Mixer' self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer_track_nav_layer = Layer( track_bank_left_button=(make_button(116, 'Mixer_Track_Left_Button')), track_bank_right_button=(make_button(117, 'Mixer_Track_Right_Button'))) for index in range(8): strip = self._mixer.channel_strip(index) strip.name = 'Channel_Strip_' + str(index) strip.empty_color = Colors.LED_OFF strip.set_invert_mute_feedback(True) mute_button = make_button((pad_identifiers[index]), ('Track_Mute_Button_' + str(index)), is_pad=True) mute_button.set_on_off_values(Colors.AMBER_FULL, Colors.AMBER_THIRD) strip.set_mute_button(mute_button) self._on_selected_send_index.subject = self._mixer self._on_selected_mixer_mode.subject = self._mixer def _init_session(self): make_button = partial(make_launch_control_button, channel=9) make_encoder = partial(make_launch_control_encoder, channel=9) bottom_encoders, top_encoders = make_all_encoders( 'Session_Mixer', make_encoder) pan_volume_layer = Layer( volume_controls=ButtonMatrixElement(rows=[bottom_encoders]), pan_controls=ButtonMatrixElement(rows=[top_encoders])) self._session_mixer = SpecialMixerComponent(8, Layer(), pan_volume_layer, Layer()) self._session_mixer.set_enabled(False) self._session_mixer.name = 'Session_Mixer' clip_launch_buttons = [ make_button(identifier, ('Clip_Launch_Button_' + str(i)), is_pad=True) for i, identifier in enumerate(pad_identifiers) ] self._session = SpecialSessionComponent(num_tracks=8, num_scenes=0, name='Session') self._session.set_enabled(False) self._session.set_mixer(self._session_mixer) self._session_layer = Layer( track_bank_left_button=(make_button(116, 'Track_Bank_Left_Button')), track_bank_right_button=(make_button(117, 'Track_Bank_Right_Button')), select_prev_button=(make_button(114, 'Scene_Bank_Up_Button')), select_next_button=(make_button(115, 'Scene_Bank_Down_Button')), clip_launch_buttons=ButtonMatrixElement( rows=[clip_launch_buttons])) scene = self._session.selected_scene() for index in range(8): clip_slot = scene.clip_slot(index) clip_slot.set_triggered_to_play_value(Colors.GREEN_BLINK) clip_slot.set_triggered_to_record_value(Colors.RED_BLINK) clip_slot.set_stopped_value(Colors.AMBER_FULL) clip_slot.set_started_value(Colors.GREEN_FULL) clip_slot.set_recording_value(Colors.RED_FULL) clip_slot.name = 'Selected_Clip_Slot_' + str(index) self._on_track_offset.subject = self._session def _init_device(self): make_button = partial(make_launch_control_button, channel=10) make_encoder = partial(make_launch_control_encoder, channel=10) bottom_encoders, top_encoders = make_all_encoders( 'Device', make_encoder) parameter_controls = top_encoders[:4] + bottom_encoders[:4] bank_buttons = [ make_button(identifier, ('Device_Bank_Button_' + str(i)), is_pad=True) for i, identifier in enumerate(pad_identifiers) ] for button in bank_buttons: button.set_on_off_values(Colors.LED_ON, Colors.LED_OFF) self._device_bank_registry = DeviceBankRegistry() self._device = DeviceComponent( device_bank_registry=(self._device_bank_registry), name='Device', device_selection_follows_track_selection=True) self._device.set_enabled(False) self._device.layer = Layer( parameter_controls=ButtonMatrixElement(rows=[parameter_controls]), bank_buttons=ButtonMatrixElement(rows=[bank_buttons])) self.set_device_component(self._device) self._device_navigation = DeviceNavigationComponent() self._device_navigation.set_enabled(False) self._device_navigation.name = 'Device_Navigation' self._device_navigation.layer = Layer( next_device_button=(make_button(115, 'Next_Device_Button')), previous_device_button=(make_button(114, 'Prev_Device_Button'))) self._view_control = ViewControlComponent() self._view_control.set_enabled(False) self._view_control.name = 'View_Control' self._view_control.layer = Layer( next_track_button=(make_button(117, 'Device_Next_Track_Button')), prev_track_button=(make_button(116, 'Device_Prev_Track_Button'))) def _init_modes(self): self._modes = ModesComponent(is_root=True) self._modes.add_mode('mixer', [ partial(self._session.set_mixer, self._mixer), LayerMode(self._session, self._mixer_track_nav_layer), self._mixer, self._session, self._show_controlled_tracks_message ]) self._modes.add_mode('session', [ partial(self._session.set_mixer, self._session_mixer), LayerMode(self._session, self._session_layer), self._session_mixer, self._session, self._show_controlled_tracks_message ]) self._modes.add_mode( 'device', [self._device, self._device_navigation, self._view_control]) self._modes.add_mode('user', None) self._modes.selected_mode = 'mixer' self._modes.layer = Layer( mixer_button=(ButtonSysexControl(Sysex.MIXER_MODE)), session_button=(ButtonSysexControl(Sysex.SESSION_MODE)), device_button=(ButtonSysexControl(Sysex.DEVICE_MODE))) @subject_slot('offset') def _on_track_offset(self): self._show_controlled_tracks_message() @subject_slot('selected_send_index') def _on_selected_send_index(self, index): self._show_controlled_sends_message() @subject_slot('selected_mixer_mode') def _on_selected_mixer_mode(self, mode): if mode == 'sends': self._show_controlled_sends_message() else: self.show_message('Controlling Pan and Volume') def _show_controlled_tracks_message(self): start = self._session.track_offset() + 1 end = min(start + 8, len(self._session.tracks_to_use())) if start < end: self.show_message('Controlling Track %d to %d' % (start, end)) else: self.show_message('Controlling Track %d' % start) def _show_controlled_sends_message(self): send_index = self._mixer.selected_send_index send_name1 = chr(ord('A') + send_index) if send_index + 1 < self._mixer.num_sends: send_name2 = chr(ord('A') + send_index + 1) self.show_message('Controlling Send %s and %s' % (send_name1, send_name2)) else: self.show_message('Controlling Send %s' % send_name1) def handle_sysex(self, midi_bytes): super(LaunchControl, self).handle_sysex(midi_bytes) if self._is_user_mode_message(midi_bytes): self._modes.selected_mode = 'user' self.request_rebuild_midi_map() def _is_user_mode_message(self, midi_bytes): return midi_bytes[:7] == Sysex.MODE_CHANGE_PREFIX and midi_bytes not in SYSEX_MODE_MAP
class KeyLab(ArturiaControlSurface): def __init__(self, *a, **k): (super(KeyLab, self).__init__)(*a, **k) with self.component_guard(): self._create_controls() self._create_display() self._create_device() self._create_drums() self._create_transport() self._create_session() self._create_session_recording() self._create_mixer() def _create_controls(self): self._device_encoders = ButtonMatrixElement(rows=[[ EncoderElement(MIDI_CC_TYPE, ENCODER_CHANNEL, identifier, (Live.MidiMap.MapMode. relative_smooth_binary_offset), name=('Device_Encoder_%d_%d' % (col_index, row_index))) for col_index, identifier in enumerate(row) ] for row_index, row in enumerate((ENCODER_MSG_IDS[:4], ENCODER_MSG_IDS[4:8]))]) self._horizontal_scroll_encoder = EncoderElement( MIDI_CC_TYPE, ENCODER_CHANNEL, (ENCODER_MSG_IDS[(-2)]), (Live.MidiMap.MapMode.relative_smooth_binary_offset), name='Horizontal_Scroll_Encoder') self._vertical_scroll_encoder = EncoderElement( MIDI_CC_TYPE, ENCODER_CHANNEL, (ENCODER_MSG_IDS[(-1)]), (Live.MidiMap.MapMode.relative_smooth_binary_offset), name='Vertical_Scroll_Encoder') self._volume_sliders = ButtonMatrixElement(rows=[[ SliderElement(MIDI_CC_TYPE, ENCODER_CHANNEL, identifier) for identifier in SLIDER_MSG_IDS[:-1] ]]) self._master_slider = SliderElement(MIDI_CC_TYPE, ENCODER_CHANNEL, SLIDER_MSG_IDS[(-1)]) def make_keylab_button(name): button = ButtonElement(True, MIDI_CC_TYPE, 0, (get_button_identifier_by_name(name)), name=(name.title())) return button for button_name in list(BUTTON_HARDWARE_AND_MESSAGE_IDS.keys()): setattr(self, '_' + button_name, make_keylab_button(button_name)) self._pads = ButtonMatrixElement(rows=[[ ButtonElement(True, MIDI_CC_TYPE, PAD_CHANNEL, (col_index + row_offset), name=('Pad_%d_%d' % (col_index, row_index))) for col_index in range(4) ] for row_index, row_offset in enumerate(range(48, 35, -4))]) def _create_display(self): self._display_line1, self._display_line2 = DisplayElement( 16, 1), DisplayElement(16, 1) for index, display_line in enumerate( (self._display_line1, self._display_line2)): display_line.set_message_parts(SETUP_MSG_PREFIX + (4, 0, 96), SETUP_MSG_SUFFIX) display_line.segment(0).set_position_identifier((index + 1, )) def adjust_null_terminated_string(string, width): return string.ljust(width, ' ') + '\x00' self._display_line1_data_source, self._display_line2_data_source = DisplayDataSource( adjust_string_fn=adjust_null_terminated_string), DisplayDataSource( adjust_string_fn=adjust_null_terminated_string) self._display_line1.segment(0).set_data_source( self._display_line1_data_source) self._display_line2.segment(0).set_data_source( self._display_line2_data_source) self._display_line1_data_source.set_display_string('KeyLab') self._display_line2_data_source.set_display_string('Ableton Live') 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) self._device_navigation = DeviceNavigationComponent( name='Device_Navigation', is_enabled=False, layer=Layer(device_nav_left_button=(self._device_left_button), device_nav_right_button=(self._device_right_button))) self._device_navigation.set_enabled(True) def _create_drums(self): self._drums = DrumRackComponent(name='Drums', is_enabled=False, layer=Layer(pads=(self._pads))) self._drums.set_enabled(True) 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), loop_button=(self._loop_button))) self._transport.set_enabled(True) def _create_session(self): self._session = SessionComponent( num_tracks=8, num_scenes=1, name='Session', is_enabled=False, layer=Layer( select_next_button=(self._scene_down_button), select_prev_button=(self._scene_up_button), selected_scene_launch_button=(self._scene_launch_button), stop_all_clips_button=(self._stop_all_clips_button), scene_select_encoder=(self._vertical_scroll_encoder))) self._session.set_enabled(True) def _create_session_recording(self): self._session_recording = SessionRecordingComponent( (ClipCreator()), (ViewControlComponent()), name='Session_Recording', is_enabled=False, layer=Layer(record_button=(self._session_record_button))) self._session_recording.set_enabled(True) def _create_mixer(self): self._mixer = MixerComponent( num_tracks=(self._volume_sliders.width()), name='Mixer', is_enabled=False, layer=Layer( volume_controls=(self._volume_sliders), track_select_encoder=(self._horizontal_scroll_encoder))) self._mixer.master_strip().layer = Layer( volume_control=(self._master_slider)) self._mixer.set_enabled(True) def _collect_setup_messages(self): for hardware_id, identifier in zip(ENCODER_HARDWARE_IDS, ENCODER_MSG_IDS): self._setup_hardware_encoder(hardware_id, identifier, ENCODER_CHANNEL) for hardware_id, identifier in zip(SLIDER_HARDWARE_IDS, SLIDER_MSG_IDS): self._setup_hardware_slider(hardware_id, identifier, ENCODER_CHANNEL) for hardware_id, identifier in BUTTON_HARDWARE_AND_MESSAGE_IDS.values( ): self._setup_hardware_button(hardware_id, identifier) for hardware_id, identifier in zip(PAD_HARDWARE_IDS, PAD_MSG_IDS): self._setup_hardware_pad(hardware_id, identifier) def _setup_hardware_encoder(self, hardware_id, identifier, channel=0): self._set_encoder_cc_msg_type(hardware_id, is_relative=True) self._set_identifier(hardware_id, identifier) self._set_channel(hardware_id, channel) def _setup_hardware_button(self, hardware_id, identifier, channel=0, **k): self._set_encoder_cc_msg_type(hardware_id) self._set_identifier(hardware_id, identifier) self._set_channel(hardware_id, channel) self._set_value_minimum(hardware_id) self._set_value_maximum(hardware_id) def _setup_hardware_pad(self, hardware_id, identifier, channel=PAD_CHANNEL): self._set_pad_note_msg_type(hardware_id) self._set_identifier(hardware_id, identifier) self._set_channel(hardware_id, channel) def _set_pad_note_msg_type(self, hardware_id): self._collect_setup_message(MODE_PROPERTY, hardware_id, PAD_NOTE_MODE) def _setup_hardware(self): for msg in self._messages_to_send: self._tasks.add( Task.sequence(partial(self._send_midi, msg), Task.wait(MESSAGE_DELAY))) self._messages_to_send = []
class Roland_A_PRO(ControlSurface): def __init__(self, *a, **k): (super(Roland_A_PRO, self).__init__)(*a, **k) with self.component_guard(): self._create_controls() self._create_transport() self._create_mixer() self._create_device() self._create_drums() self._create_modes() def _create_controls(self): self._encoders = ButtonMatrixElement(rows=[ [EncoderElement(MIDI_CC_TYPE, 0, identifier, (Live.MidiMap.MapMode.absolute), name=('Encoder_%d' % index)) for index, identifier in enumerate(ENCODER_IDS)]]) self._master_encoder = EncoderElement(MIDI_CC_TYPE, 0, 10, (Live.MidiMap.MapMode.absolute), name='Master_Encoder') self._sliders = ButtonMatrixElement(rows=[ [SliderElement(MIDI_CC_TYPE, 0, identifier, name=('Slider_%d' % index)) for index, identifier in enumerate(SLIDER_IDS)]]) self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 7, name='Master_Slider') self._play_button = ButtonElement(True, MIDI_CC_TYPE, 0, 26) self._stop_button = ButtonElement(True, MIDI_CC_TYPE, 0, 25) self._record_button = ButtonElement(True, MIDI_CC_TYPE, 0, 28) self._forward_button = ButtonElement(True, MIDI_CC_TYPE, 0, 24) self._backward_button = ButtonElement(True, MIDI_CC_TYPE, 0, 21) self._ff_button = ButtonElement(True, MIDI_CC_TYPE, 0, 23) self._rw_button = ButtonElement(True, MIDI_CC_TYPE, 0, 22) self._device_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 80) self._pan_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 81) self._send_a_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 82) self._send_b_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 83) self._pads = ButtonMatrixElement(rows=[[ButtonElement(True, MIDI_NOTE_TYPE, 0, identifier) for identifier in row] for row in PAD_ROWS]) def _create_transport(self): self._transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer(play_button=(self._play_button), stop_button=(self._stop_button), record_button=(self._record_button))) self._transport.set_enabled(True) def _create_mixer(self): mixer_size = self._sliders.width() self._mixer = MixerComponent(mixer_size, name='Mixer', is_enabled=False, layer=Layer(volume_controls=(self._sliders), prehear_volume_control=(self._master_encoder))) self._mixer.master_strip().layer = Layer(volume_control=(self._master_slider)) self._mixer.set_enabled(True) def _create_device(self): self._device = DeviceComponent(device_selection_follows_track_selection=True) self._device_navigation = DeviceNavigationComponent() self._device.set_enabled(True) self._device_navigation.set_enabled(True) self.set_device_component(self._device) def _create_drums(self): self._drums = DrumRackComponent(name='Drum_Rack', is_enabled=False, layer=Layer(pads=(self._pads))) self._drums.set_enabled(True) def _create_modes(self): self._encoder_modes = ModesComponent() device_layer_mode = LayerMode(self._device, Layer(parameter_controls=(self._encoders))) device_navigation_layer_mode = LayerMode(self._device_navigation, Layer(device_nav_right_button=(self._forward_button), device_nav_left_button=(self._backward_button))) self._encoder_modes.add_mode('device_mode', [device_layer_mode, device_navigation_layer_mode]) self._encoder_modes.add_mode('pan_mode', AddLayerMode(self._mixer, Layer(pan_controls=(self._encoders), bank_up_button=(self._forward_button), bank_down_button=(self._backward_button), track_up_button=(self._ff_button), track_down_button=(self._rw_button)))) send_layer_mode = AddLayerMode(self._mixer, Layer(send_controls=(self._encoders), bank_up_button=(self._forward_button), bank_down_button=(self._backward_button), track_up_button=(self._ff_button), track_down_button=(self._rw_button))) self._encoder_modes.add_mode('send_a_mode', [send_layer_mode, partial(self._set_send_index, 0)]) self._encoder_modes.add_mode('send_b_mode', [send_layer_mode, partial(self._set_send_index, 1)]) self._encoder_modes.layer = Layer(device_mode_button=(self._device_mode_button), pan_mode_button=(self._pan_mode_button), send_a_mode_button=(self._send_a_mode_button), send_b_mode_button=(self._send_b_mode_button)) self._encoder_modes.selected_mode = 'device_mode' self._encoder_modes.set_enabled(True) def _set_send_index(self, index): self._mixer.send_index = index
class MiniLab(ArturiaControlSurface): session_component_type = SessionComponent encoder_msg_channel = 0 encoder_msg_ids = (7, 74, 71, 76, 77, 93, 73, 75, 114, 18, 19, 16, 17, 91, 79, 72) pad_channel = 9 def __init__(self, *a, **k): (super(MiniLab, self).__init__)(*a, **k) with self.component_guard(): self._create_controls() self._create_device() self._create_session() self._create_mixer() def _create_controls(self): self._device_controls = ButtonMatrixElement(rows=[[EncoderElement(MIDI_CC_TYPE, (self.encoder_msg_channel), 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(( self.encoder_msg_ids[:4], self.encoder_msg_ids[8:12]))]) self._horizontal_scroll_encoder = EncoderElement(MIDI_CC_TYPE, (self.encoder_msg_channel), (self.encoder_msg_ids[7]), (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Horizontal_Scroll_Encoder') self._vertical_scroll_encoder = EncoderElement(MIDI_CC_TYPE, (self.encoder_msg_channel), (self.encoder_msg_ids[15]), (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Vertical_Scroll_Encoder') self._volume_encoder = EncoderElement(MIDI_CC_TYPE, (self.encoder_msg_channel), (self.encoder_msg_ids[13]), (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Volume_Encoder') self._pan_encoder = EncoderElement(MIDI_CC_TYPE, (self.encoder_msg_channel), (self.encoder_msg_ids[12]), (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Pan_Encoder') self._send_a_encoder = EncoderElement(MIDI_CC_TYPE, (self.encoder_msg_channel), (self.encoder_msg_ids[4]), (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Send_A_Encoder') self._send_b_encoder = EncoderElement(MIDI_CC_TYPE, (self.encoder_msg_channel), (self.encoder_msg_ids[5]), (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, (self.encoder_msg_channel), (self.encoder_msg_ids[6]), (Live.MidiMap.MapMode.relative_smooth_two_compliment), name='Return_A_Encoder') self._return_b_encoder = EncoderElement(MIDI_CC_TYPE, (self.encoder_msg_channel), (self.encoder_msg_ids[14]), (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, (self.pad_channel), (col + 36 + 8 * row), name=('Pad_%d_%d' % (col, row))) for col in range(8)] for row in range(2)]) def _create_device(self): self._device = DeviceComponent(name='Device', is_enabled=False, layer=Layer(parameter_controls=(self._device_controls)), device_selection_follows_track_selection=True) self._device.set_enabled(True) self.set_device_component(self._device) def _create_session(self): self._session = self.session_component_type(num_tracks=(self._pads.width()), num_scenes=(self._pads.height()), name='Session', is_enabled=False, 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 _collect_setup_messages(self): for cc_id, encoder_id in zip(self.encoder_msg_ids, HARDWARE_ENCODER_IDS): self._setup_hardware_encoder(encoder_id, cc_id, channel=(self.encoder_msg_channel)) for index, pad_id in enumerate(HARDWARE_BUTTON_IDS): self._setup_hardware_button(pad_id, index + PAD_IDENTIFIER_OFFSET, self.pad_channel)
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')