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 izip(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 izip(HARDWARE_PAD_IDS, chain(*PAD_MSG_IDS)): self._setup_hardware_button(hardware_id, identifier, PAD_CHANNEL, msg_type='note')
def __init__(self, *a, **k): super(Advance, self).__init__(*a, **k) with self.component_guard(): encoders = ButtonMatrixElement(rows=[[ make_encoder(index + 22, b'Encoder_%d' % index) for index in xrange(8) ]]) pads = ButtonMatrixElement(rows=[[ make_button(identifier, b'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, b'Play_Button', MIDI_CC_TYPE, 0) stop_button = make_button(117, b'Stop_Button', MIDI_CC_TYPE, 0) record_button = make_button(119, b'Record_Button', MIDI_CC_TYPE, 0) loop_button = make_button(114, b'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(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.set_enabled(True) self.set_device_component(device) self._device_selection_follows_track_selection = True
def __init__(self, *a, **k): super(MPK261, 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) mixer_size = len(midimap['Sliders']) mixer = MixerComponent(mixer_size, name='Mixer', is_enabled=False, layer=Layer( volume_controls=midimap['Sliders'], pan_controls=midimap['Encoders'], arm_buttons=midimap['Arm_Buttons'])) mixer.set_enabled(True)
def __init__(self, *a, **k): super(Alesis_VI, self).__init__(*a, **k) with self.component_guard(): midimap = MidiMap() transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer(play_button=midimap['Play'], stop_button=midimap['Stop'], loop_button=midimap['Loop'], record_button=midimap['Record'], seek_forward_button=midimap['Forward'], seek_backward_button=midimap['Backward'])) mixer_size = len(midimap['Volume_Encoders']) mixer = MixerComponent(mixer_size, name='Mixer', is_enabled=False, layer=Layer(volume_controls=midimap['Volume_Encoders'])) transport.set_enabled(True) mixer.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)
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)) self._device.set_enabled(True) self.set_device_component(self._device) self._device_selection_follows_track_selection = True 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 izip(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 izip(HARDWARE_PAD_IDS, chain(*PAD_MSG_IDS)): self._setup_hardware_button(hardware_id, identifier, PAD_CHANNEL, msg_type='note')
def __init__(self, *a, **k): super(MPK249, 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) mixer_size = len(midimap['Sliders']) mixer = MixerComponent(mixer_size, name='Mixer', is_enabled=False, layer=Layer(volume_controls=midimap['Sliders'], pan_controls=midimap['Encoders'], arm_buttons=midimap['Arm_Buttons'])) mixer.set_enabled(True)
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 xrange(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)
class KeyPad(ControlSurface): """ Reloop KeyPad controller script. """ _encoder_range = range(73, 81) _product_model_id = 101 def __init__(self, c_instance): super(KeyPad, self).__init__(c_instance) with self.component_guard(): self._create_controls() self._setup_mixer() self._setup_transport() self._setup_session() self._setup_cue_control() self.set_pad_translations(PAD_TRANSLATIONS) def _preset_message(self, send_byte): """ Sysex message for setting the preset to #2. """ return (240, 38, self._product_model_id, send_byte, 17, 2, 247) def refresh_state(self): super(KeyPad, self).refresh_state() self.schedule_message(2, self._send_midi, self._preset_message(1)) def handle_sysex(self, midi_bytes): if midi_bytes != self._preset_message(2): super(KeyPad, self).handle_sysex(midi_bytes) else: map(lambda x: x.set_enabled(True), (self._mixer, self._session, self._transport, self._cue_control)) def _create_controls(self): def make_controls_range(maker, label, cc_range): ccs = [(index + 1, cc) for index, cc in enumerate(cc_range)] return [maker(1, cc, label % index) for index, cc in ccs] + [ maker(2, cc, label % (index + len(ccs))) for index, cc in ccs ] def make_controls(maker, label, cc_offset): return make_controls_range(maker, label, xrange(cc_offset, cc_offset + 8)) make_non_momentary_button = partial(make_button, is_momentary=False) self._encoders = make_controls(make_encoder, 'Encoder_%d', 57) self._rotaries_a = make_controls(make_slider, 'Rotary_A%d', 89) self._rotaries_b = make_controls(make_slider, 'Rotary_B%d', 97) self._faders = make_controls(make_slider, 'Fader_%d', 0) self._mute_buttons = make_controls(make_non_momentary_button, 'Mute_%d_Button', 8) self._solo_buttons = make_controls(make_button, 'Solo_%d_Button', 24) self._arm_buttons = make_controls(make_button, 'Arm_%d_Button', 40) self._play_button = make_button(1, 105, 'Play_Button') self._stop_button = make_button(1, 106, 'Stop_Button') self._record_button = make_button(1, 107, 'Record_Button') self._encoder_pushes = make_controls_range( partial(make_button, is_momentary=False), 'Encoder_%d_Button', self._encoder_range) self._shifted_mute_buttons = make_controls(make_non_momentary_button, 'Shifted_Mute_%d_Button', 16) self._shifted_solo_buttons = make_controls(make_button, 'Shifted_Solo_%d_Button', 32) self._all_shifted_arm_buttons = make_controls(make_button, 'Shifted_Arm_%d_Button', 49) self._shifted_arm_buttons = [ CombinedButtonsElement( buttons=(self._all_shifted_arm_buttons[index], self._all_shifted_arm_buttons[index + 8])) for index in xrange(8) ] self._shifted_play_button = make_button(1, 108, 'Shifted_Play_Button') self._shifted_stop_button = make_button(1, 109, 'Shifted_Stop_Button') self._shifted_record_button = make_button(1, 110, 'Shifted_Record_Button') self._shifted_octave_down_button = make_button( 1, 111, 'Shifted_Octave_Down_Button') self._shifted_octave_up_button = make_button( 1, 112, 'Shifted_Octave_Up_Button') def _setup_mixer(self): self._mixer = MixerComponent(NUM_CHANNEL_STRIPS) self._mixer.name = 'Mixer' self._mixer.set_enabled(False) for index in xrange(NUM_CHANNEL_STRIPS): strip = self._mixer.channel_strip(index) strip.set_invert_mute_feedback(True) sends = ButtonMatrixElement(name='%d_Send_Controls' % (index + 1), rows=[(self._rotaries_a[index], self._rotaries_b[index])]) strip.layer = Layer(volume_control=self._faders[index], pan_control=self._encoders[index], send_controls=sends, mute_button=self._mute_buttons[index], solo_button=self._solo_buttons[index], arm_button=self._arm_buttons[index], select_button=self._encoder_pushes[index]) def _setup_transport(self): self._transport = TransportComponent(name='Transport') self._transport.set_enabled(False) self._transport.layer = Layer( play_button=self._play_button, stop_button=self._stop_button, record_button=self._record_button, overdub_button=self._shifted_record_button, loop_button=self._shifted_arm_buttons[3], tap_tempo_button=self._shifted_arm_buttons[4], metronome_button=self._shifted_arm_buttons[5], nudge_down_button=self._shifted_arm_buttons[6], nudge_up_button=self._shifted_arm_buttons[7]) def _setup_session(self): self._session = SessionComponent(NUM_CHANNEL_STRIPS, name='Session_Control') self._session.set_enabled(False) stop_buttons = ButtonMatrixElement(name='Track_Stop_Buttons', rows=[self._shifted_solo_buttons]) self._session.layer = Layer( stop_all_clips_button=self._shifted_stop_button, stop_track_clip_buttons=stop_buttons, select_prev_button=self._shifted_octave_down_button, select_next_button=self._shifted_octave_up_button) self._session.selected_scene().name = 'Selected_Scene_Control' self._session.selected_scene().layer = Layer( launch_button=self._shifted_play_button) for index in xrange(NUM_CHANNEL_STRIPS): slot = self._session.selected_scene().clip_slot(index) slot.layer = Layer(launch_button=self._shifted_mute_buttons[index]) def _setup_cue_control(self): self._cue_control = CuePointControlComponent(name='Cue_Point_Control') self._cue_control.set_enabled(False) self._cue_control.layer = Layer( toggle_cue_button=self._shifted_arm_buttons[0], prev_cue_button=self._shifted_arm_buttons[1], next_cue_button=self._shifted_arm_buttons[2])
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 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 xrange(4) ] for row_index, row_offset in enumerate(xrange(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)) self._device.set_enabled(True) self.set_device_component(self._device) self._device_selection_follows_track_selection = True 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 izip(ENCODER_HARDWARE_IDS, ENCODER_MSG_IDS): self._setup_hardware_encoder(hardware_id, identifier, ENCODER_CHANNEL) for hardware_id, identifier in izip(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.itervalues(): self._setup_hardware_button(hardware_id, identifier) for hardware_id, identifier in izip(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)
class KeyPad(ControlSurface): """ Reloop KeyPad controller script. """ _encoder_range = range(73, 81) _product_model_id = 101 def __init__(self, c_instance): super(KeyPad, self).__init__(c_instance) with self.component_guard(): self._create_controls() self._setup_mixer() self._setup_transport() self._setup_session() self._setup_cue_control() self.set_pad_translations(PAD_TRANSLATIONS) def _preset_message(self, send_byte): """ Sysex message for setting the preset to #2. """ return (240, 38, self._product_model_id, send_byte, 17, 2, 247) def refresh_state(self): super(KeyPad, self).refresh_state() self.schedule_message(2, self._send_midi, self._preset_message(1)) def handle_sysex(self, midi_bytes): if midi_bytes != self._preset_message(2): super(KeyPad, self).handle_sysex(midi_bytes) else: map(lambda x: x.set_enabled(True), (self._mixer, self._session, self._transport, self._cue_control)) def _create_controls(self): def make_controls_range(maker, label, cc_range): ccs = [ (index + 1, cc) for index, cc in enumerate(cc_range) ] return [ maker(1, cc, label % index) for index, cc in ccs ] + [ maker(2, cc, label % (index + len(ccs))) for index, cc in ccs ] def make_controls(maker, label, cc_offset): return make_controls_range(maker, label, xrange(cc_offset, cc_offset + 8)) make_non_momentary_button = partial(make_button, is_momentary=False) self._encoders = make_controls(make_encoder, 'Encoder_%d', 57) self._rotaries_a = make_controls(make_slider, 'Rotary_A%d', 89) self._rotaries_b = make_controls(make_slider, 'Rotary_B%d', 97) self._faders = make_controls(make_slider, 'Fader_%d', 0) self._mute_buttons = make_controls(make_non_momentary_button, 'Mute_%d_Button', 8) self._solo_buttons = make_controls(make_button, 'Solo_%d_Button', 24) self._arm_buttons = make_controls(make_button, 'Arm_%d_Button', 40) self._play_button = make_button(1, 105, 'Play_Button') self._stop_button = make_button(1, 106, 'Stop_Button') self._record_button = make_button(1, 107, 'Record_Button') self._encoder_pushes = make_controls_range(partial(make_button, is_momentary=False), 'Encoder_%d_Button', self._encoder_range) self._shifted_mute_buttons = make_controls(make_non_momentary_button, 'Shifted_Mute_%d_Button', 16) self._shifted_solo_buttons = make_controls(make_button, 'Shifted_Solo_%d_Button', 32) self._all_shifted_arm_buttons = make_controls(make_button, 'Shifted_Arm_%d_Button', 49) self._shifted_arm_buttons = [ CombinedButtonsElement(buttons=(self._all_shifted_arm_buttons[index], self._all_shifted_arm_buttons[index + 8])) for index in xrange(8) ] self._shifted_play_button = make_button(1, 108, 'Shifted_Play_Button') self._shifted_stop_button = make_button(1, 109, 'Shifted_Stop_Button') self._shifted_record_button = make_button(1, 110, 'Shifted_Record_Button') self._shifted_octave_down_button = make_button(1, 111, 'Shifted_Octave_Down_Button') self._shifted_octave_up_button = make_button(1, 112, 'Shifted_Octave_Up_Button') def _setup_mixer(self): self._mixer = MixerComponent(NUM_CHANNEL_STRIPS) self._mixer.name = 'Mixer' self._mixer.set_enabled(False) for index in xrange(NUM_CHANNEL_STRIPS): strip = self._mixer.channel_strip(index) strip.set_invert_mute_feedback(True) sends = ButtonMatrixElement(name='%d_Send_Controls' % (index + 1), rows=[(self._rotaries_a[index], self._rotaries_b[index])]) strip.layer = Layer(volume_control=self._faders[index], pan_control=self._encoders[index], send_controls=sends, mute_button=self._mute_buttons[index], solo_button=self._solo_buttons[index], arm_button=self._arm_buttons[index], select_button=self._encoder_pushes[index]) def _setup_transport(self): self._transport = TransportComponent(name='Transport') self._transport.set_enabled(False) self._transport.layer = Layer(play_button=self._play_button, stop_button=self._stop_button, record_button=self._record_button, overdub_button=self._shifted_record_button, loop_button=self._shifted_arm_buttons[3], tap_tempo_button=self._shifted_arm_buttons[4], metronome_button=self._shifted_arm_buttons[5], nudge_down_button=self._shifted_arm_buttons[6], nudge_up_button=self._shifted_arm_buttons[7]) def _setup_session(self): self._session = SessionComponent(NUM_CHANNEL_STRIPS, name='Session_Control') self._session.set_enabled(False) stop_buttons = ButtonMatrixElement(name='Track_Stop_Buttons', rows=[self._shifted_solo_buttons]) self._session.layer = Layer(stop_all_clips_button=self._shifted_stop_button, stop_track_clip_buttons=stop_buttons, select_prev_button=self._shifted_octave_down_button, select_next_button=self._shifted_octave_up_button) self._session.selected_scene().name = 'Selected_Scene_Control' self._session.selected_scene().layer = Layer(launch_button=self._shifted_play_button) for index in xrange(NUM_CHANNEL_STRIPS): slot = self._session.selected_scene().clip_slot(index) slot.layer = Layer(launch_button=self._shifted_mute_buttons[index]) def _setup_cue_control(self): self._cue_control = CuePointControlComponent(name='Cue_Point_Control') self._cue_control.set_enabled(False) self._cue_control.layer = Layer(toggle_cue_button=self._shifted_arm_buttons[0], prev_cue_button=self._shifted_arm_buttons[1], next_cue_button=self._shifted_arm_buttons[2])
def __init__(self, *a, **k): super(MPK261MX, self).__init__(*a, **k) self.show_message( "-----------------------= MPK261MX LOADING - maxcloutier13 says hi =----------------------------------------------------------" ) self.log_message( "-----------------------= MPK261MX LOADING - maxcloutier13 says hi =----------------------------------------------------------" ) with self.component_guard(): midimap = MidiMap() #Super crude manual init for the custom buttons and faders #Bank A - Channel 1 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- self._Encoder0 = EncoderElement( MIDI_CC_TYPE, 1, 22, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder0') self._Encoder1 = EncoderElement( MIDI_CC_TYPE, 1, 23, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder1') self._Encoder2 = EncoderElement( MIDI_CC_TYPE, 1, 24, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder2') self._Encoder3 = EncoderElement( MIDI_CC_TYPE, 1, 25, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder3') self._Encoder4 = EncoderElement( MIDI_CC_TYPE, 1, 26, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder4') self._Encoder5 = EncoderElement( MIDI_CC_TYPE, 1, 27, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder5') self._Encoder6 = EncoderElement( MIDI_CC_TYPE, 1, 28, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder6') self._Encoder7 = EncoderElement( MIDI_CC_TYPE, 1, 29, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder7') self._ArmButton0 = ButtonElement(False, MIDI_CC_TYPE, 0, 32, name='ArmButton0') self._ArmButton1 = ButtonElement(False, MIDI_CC_TYPE, 0, 33, name='ArmButton1') self._ArmButton2 = ButtonElement(False, MIDI_CC_TYPE, 0, 34, name='ArmButton2') self._ArmButton3 = ButtonElement(False, MIDI_CC_TYPE, 0, 35, name='ArmButton3') self._ArmButton4 = ButtonElement(False, MIDI_CC_TYPE, 0, 36, name='ArmButton4') self._ArmButton5 = ButtonElement(False, MIDI_CC_TYPE, 0, 37, name='ArmButton5') self._ArmButton6 = ButtonElement(False, MIDI_CC_TYPE, 0, 38, name='ArmButton6') self._ArmButton7 = ButtonElement(False, MIDI_CC_TYPE, 0, 39, name='ArmButton7') self._VolumeSlider0 = SliderElement(MIDI_CC_TYPE, 0, 12, name='VolumeSlider0') self._VolumeSlider1 = SliderElement(MIDI_CC_TYPE, 0, 13, name='VolumeSlider1') self._VolumeSlider2 = SliderElement(MIDI_CC_TYPE, 0, 14, name='VolumeSlider2') self._VolumeSlider3 = SliderElement(MIDI_CC_TYPE, 0, 15, name='VolumeSlider3') self._VolumeSlider4 = SliderElement(MIDI_CC_TYPE, 0, 16, name='VolumeSlider4') self._VolumeSlider5 = SliderElement(MIDI_CC_TYPE, 0, 17, name='VolumeSlider5') self._VolumeSlider6 = SliderElement(MIDI_CC_TYPE, 0, 18, name='VolumeSlider6') self._VolumeSlider7 = SliderElement(MIDI_CC_TYPE, 0, 19, name='VolumeSlider7') #Bank B - Channel 2 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- self._Encoder8 = EncoderElement( MIDI_CC_TYPE, 2, 22, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder8') self._Encoder9 = EncoderElement( MIDI_CC_TYPE, 2, 23, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder9') self._Encoder10 = EncoderElement( MIDI_CC_TYPE, 2, 24, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder10') self._Encoder11 = EncoderElement( MIDI_CC_TYPE, 2, 25, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder11') self._Encoder12 = EncoderElement( MIDI_CC_TYPE, 2, 26, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder12') self._Encoder13 = EncoderElement( MIDI_CC_TYPE, 2, 27, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder13') self._Encoder14 = EncoderElement( MIDI_CC_TYPE, 2, 28, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder14') self._Encoder15 = EncoderElement( MIDI_CC_TYPE, 2, 29, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder15') self._ArmButton8 = ButtonElement(False, MIDI_CC_TYPE, 1, 32, name='ArmButton8') self._ArmButton9 = ButtonElement(False, MIDI_CC_TYPE, 1, 33, name='ArmButton9') self._ArmButton10 = ButtonElement(False, MIDI_CC_TYPE, 1, 34, name='ArmButton10') self._ArmButton11 = ButtonElement(False, MIDI_CC_TYPE, 1, 35, name='ArmButton11') self._ArmButton12 = ButtonElement(False, MIDI_CC_TYPE, 1, 36, name='ArmButton12') self._ArmButton13 = ButtonElement(False, MIDI_CC_TYPE, 1, 37, name='ArmButton13') self._ArmButton14 = ButtonElement(False, MIDI_CC_TYPE, 1, 38, name='ArmButton14') self._ArmButton15 = ButtonElement(False, MIDI_CC_TYPE, 1, 39, name='ArmButton15') self._VolumeSlider8 = SliderElement(MIDI_CC_TYPE, 1, 12, name='VolumeSlider8') self._VolumeSlider9 = SliderElement(MIDI_CC_TYPE, 1, 13, name='VolumeSlider9') self._VolumeSlider10 = SliderElement(MIDI_CC_TYPE, 1, 14, name='VolumeSlider10') self._VolumeSlider11 = SliderElement(MIDI_CC_TYPE, 1, 15, name='VolumeSlider11') self._VolumeSlider12 = SliderElement(MIDI_CC_TYPE, 1, 16, name='VolumeSlider12') self._VolumeSlider13 = SliderElement(MIDI_CC_TYPE, 1, 17, name='VolumeSlider13') self._VolumeSlider14 = SliderElement(MIDI_CC_TYPE, 1, 18, name='VolumeSlider14') self._VolumeSlider15 = SliderElement(MIDI_CC_TYPE, 1, 19, name='VolumeSlider15') #Bank C - Channel 3 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- self._Encoder16 = EncoderElement( MIDI_CC_TYPE, 3, 22, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder16') self._Encoder17 = EncoderElement( MIDI_CC_TYPE, 3, 23, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder17') self._Encoder18 = EncoderElement( MIDI_CC_TYPE, 3, 24, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder18') self._Encoder19 = EncoderElement( MIDI_CC_TYPE, 3, 25, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder19') self._Encoder20 = EncoderElement( MIDI_CC_TYPE, 3, 26, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder20') self._Encoder21 = EncoderElement( MIDI_CC_TYPE, 3, 27, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder21') self._Encoder22 = EncoderElement( MIDI_CC_TYPE, 3, 28, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder22') self._Encoder23 = EncoderElement( MIDI_CC_TYPE, 3, 29, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder23') self._ArmButton16 = ButtonElement(False, MIDI_CC_TYPE, 2, 32, name='ArmButton16') self._ArmButton17 = ButtonElement(False, MIDI_CC_TYPE, 2, 33, name='ArmButton17') self._ArmButton18 = ButtonElement(False, MIDI_CC_TYPE, 2, 34, name='ArmButton18') self._ArmButton19 = ButtonElement(False, MIDI_CC_TYPE, 2, 35, name='ArmButton19') self._ArmButton20 = ButtonElement(False, MIDI_CC_TYPE, 2, 36, name='ArmButton20') self._ArmButton21 = ButtonElement(False, MIDI_CC_TYPE, 2, 37, name='ArmButton21') self._ArmButton22 = ButtonElement(False, MIDI_CC_TYPE, 2, 38, name='ArmButton22') self._ArmButton23 = ButtonElement(False, MIDI_CC_TYPE, 2, 39, name='ArmButton23') self._VolumeSlider16 = SliderElement(MIDI_CC_TYPE, 2, 12, name='VolumeSlider16') self._VolumeSlider17 = SliderElement(MIDI_CC_TYPE, 2, 13, name='VolumeSlider17') self._VolumeSlider18 = SliderElement(MIDI_CC_TYPE, 2, 14, name='VolumeSlider18') self._VolumeSlider19 = SliderElement(MIDI_CC_TYPE, 2, 15, name='VolumeSlider19') self._VolumeSlider20 = SliderElement(MIDI_CC_TYPE, 2, 16, name='VolumeSlider20') self._VolumeSlider21 = SliderElement(MIDI_CC_TYPE, 2, 17, name='VolumeSlider21') self._VolumeSlider22 = SliderElement(MIDI_CC_TYPE, 2, 18, name='VolumeSlider22') self._VolumeSlider23 = SliderElement(MIDI_CC_TYPE, 2, 19, name='VolumeSlider23') #Drum rack ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- drum_rack = DrumRackComponent( name='Drum_Rack', is_enabled=False, layer=Layer(pads=midimap['Drum_Pads'])) drum_rack.set_enabled(True) #Transport ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer( play_button=midimap['Play'], record_button=midimap['Record'], stop_button=midimap['Stop'], loop_button=midimap['Loop'])) #, seek_forward_button=midimap['Forward'], seek_backward_button=midimap['Backward'] transport.set_enabled(True) #Make the Back/Fwd button just normal mapable CC senders self._BackButton = ButtonElement(False, MIDI_CC_TYPE, 0, 116, name='BackButton') self._FwdButton = ButtonElement(False, MIDI_CC_TYPE, 0, 115, name='FwdButton') #Device ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- self._device = DeviceComponent( name='Device', is_enabled=False, layer=Layer(parameter_controls=midimap['Encoders']), device_selection_follows_track_selection=True) self._device.set_enabled(True) self.set_device_component(self._device) #Mixer ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- mixer_size = 24 self._mixer = MixerComponent(mixer_size, name='Mixer', is_enabled=False) #Super crude and repetitive mapping because after all this shit I'm not spending time learning how to loop this crap hehe #Bank A self._mixer.channel_strip(0).layer = Layer( volume_control=self._VolumeSlider0, arm_button=self._ArmButton0, pan_control=self._Encoder0) self._mixer.channel_strip(1).layer = Layer( volume_control=self._VolumeSlider1, arm_button=self._ArmButton1, pan_control=self._Encoder1) self._mixer.channel_strip(2).layer = Layer( volume_control=self._VolumeSlider2, arm_button=self._ArmButton2, pan_control=self._Encoder2) self._mixer.channel_strip(3).layer = Layer( volume_control=self._VolumeSlider3, arm_button=self._ArmButton3, pan_control=self._Encoder3) self._mixer.channel_strip(4).layer = Layer( volume_control=self._VolumeSlider4, arm_button=self._ArmButton4, pan_control=self._Encoder4) self._mixer.channel_strip(5).layer = Layer( volume_control=self._VolumeSlider5, arm_button=self._ArmButton5, pan_control=self._Encoder5) self._mixer.channel_strip(6).layer = Layer( volume_control=self._VolumeSlider6, arm_button=self._ArmButton6, pan_control=self._Encoder6) self._mixer.channel_strip(7).layer = Layer( volume_control=self._VolumeSlider7, arm_button=self._ArmButton7, pan_control=self._Encoder7) #Bank B self._mixer.channel_strip(8).layer = Layer( volume_control=self._VolumeSlider8, arm_button=self._ArmButton8, pan_control=self._Encoder8) self._mixer.channel_strip(9).layer = Layer( volume_control=self._VolumeSlider9, arm_button=self._ArmButton9, pan_control=self._Encoder9) self._mixer.channel_strip(10).layer = Layer( volume_control=self._VolumeSlider10, arm_button=self._ArmButton10, pan_control=self._Encoder10) self._mixer.channel_strip(11).layer = Layer( volume_control=self._VolumeSlider11, arm_button=self._ArmButton11, pan_control=self._Encoder11) self._mixer.channel_strip(12).layer = Layer( volume_control=self._VolumeSlider12, arm_button=self._ArmButton12, pan_control=self._Encoder12) self._mixer.channel_strip(13).layer = Layer( volume_control=self._VolumeSlider13, arm_button=self._ArmButton13, pan_control=self._Encoder13) self._mixer.channel_strip(14).layer = Layer( volume_control=self._VolumeSlider14, arm_button=self._ArmButton14, pan_control=self._Encoder14) self._mixer.channel_strip(15).layer = Layer( volume_control=self._VolumeSlider15, arm_button=self._ArmButton15, pan_control=self._Encoder15) #Bank C self._mixer.channel_strip(16).layer = Layer( volume_control=self._VolumeSlider16, arm_button=self._ArmButton16, pan_control=self._Encoder16) self._mixer.channel_strip(17).layer = Layer( volume_control=self._VolumeSlider17, arm_button=self._ArmButton17, pan_control=self._Encoder17) self._mixer.channel_strip(18).layer = Layer( volume_control=self._VolumeSlider18, arm_button=self._ArmButton18, pan_control=self._Encoder18) self._mixer.channel_strip(19).layer = Layer( volume_control=self._VolumeSlider19, arm_button=self._ArmButton19, pan_control=self._Encoder19) self._mixer.channel_strip(20).layer = Layer( volume_control=self._VolumeSlider20, arm_button=self._ArmButton20, pan_control=self._Encoder20) self._mixer.channel_strip(21).layer = Layer( volume_control=self._VolumeSlider21, arm_button=self._ArmButton21, pan_control=self._Encoder21) self._mixer.channel_strip(22).layer = Layer( volume_control=self._VolumeSlider22, arm_button=self._ArmButton22, pan_control=self._Encoder22) self._mixer.channel_strip(23).layer = Layer( volume_control=self._VolumeSlider23, arm_button=self._ArmButton23, pan_control=self._Encoder23) self._mixer.set_enabled(True) #-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
class OhmModes(ControlSurface): __module__ = __name__ __doc__ = ' OhmModes controller script ' def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._version_check = 'b994' self._host_name = 'Ohm' self._color_type = 'OhmRGB' self._hosts = [] self.hosts = [] self._client = [ None for index in range(6) ] self._active_client = None self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< OhmModes ' + str(self._version_check) + ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>') self._rgb = 0 self._timer = 0 self._touched = 0 self.flash_status = 1 self._backlight = 127 self._backlight_type = 'static' self._ohm = 127 self._ohm_type = 'static' self._pad_translations = PAD_TRANSLATION self._device_selection_follows_track_selection = FOLLOW self._keys_octave = 5 self._keys_scale = 0 self._tempo_buttons = None self._setup_monobridge() self._setup_controls() self._setup_transport_control() self._setup_mixer_control() self._setup_session_control() self._setup_device_control() self._setup_crossfader() self._setup_ohmmod() self._setup_switchboard() self._setup_modes() self._assign_page_constants() self._last_device = None self.song().view.add_selected_track_listener(self._update_selected_device) self.show_message('OhmModes Control Surface Loaded') self._send_midi(tuple(switchxfader)) if FORCE_TYPE is True: self._rgb = FORCE_COLOR_TYPE else: self.schedule_message(10, self.query_ohm, None) self.log_message(str(self._highlighting_session_component)) def query_ohm(self): self._send_midi(tuple(check_model)) def update_display(self): ControlSurface.update_display(self) self._timer = (self._timer + 1) % 256 self.flash() self.strobe() def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def get_device_bank(self): return self._device._bank_index def _setup_controls(self): is_momentary = True self._fader = [ None for index in range(8) ] self._dial = [ None for index in range(16) ] self._button = [ None for index in range(8) ] self._menu = [ None for index in range(6) ] for index in range(8): self._fader[index] = MonoEncoderElement2(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self) for index in range(8): self._button[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self) for index in range(16): self._dial[index] = CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), index, self) self._knobs = [] for index in range(12): self._knobs.append(self._dial[index]) for index in range(6): self._menu[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self) self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute) self._crossfader.name = 'Crossfader' self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self) self._shift_l = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Page_Button_Left', self) self._shift_r = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Page_Button_Right', self) self._matrix = ButtonMatrixElement() self._matrix.name = 'Matrix' self._grid = [ None for index in range(8) ] self._monomod = ButtonMatrixElement() self._monomod.name = 'Monomod' for column in range(8): self._grid[column] = [ None for index in range(8) ] for row in range(8): self._grid[column][row] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, column * 8 + row, 'Grid_' + str(column) + '_' + str(row), self) for row in range(5): button_row = [] for column in range(7): button_row.append(self._grid[column][row]) self._matrix.add_row(tuple(button_row)) for row in range(8): button_row = [] for column in range(8): button_row.append(self._grid[column][row]) self._monomod.add_row(tuple(button_row)) self._mod_matrix = ButtonMatrixElement() self._mod_matrix.name = 'Matrix' self._dial_matrix = EncoderMatrixElement(self) self._dial_matrix.name = 'Dial_Matrix' self._dial_button_matrix = ButtonMatrixElement() self._dial_button_matrix.name = 'Dial_Button_Matrix' for row in range(4): button_row = [] for column in range(4): button_row.append(self._grid[column + 4][row]) self._mod_matrix.add_row(tuple(button_row)) for row in range(3): dial_row = [] for column in range(4): dial_row.append(self._dial[row * 4 + column]) self._dial_matrix.add_row(tuple(dial_row)) for row in range(3): dial_button_row = [] for column in range(4): dial_button_row.append(self._grid[column][row]) self._dial_button_matrix.add_row(tuple(dial_button_row)) self._key = [ self._grid[KEYS[index][1]][KEYS[index][0]] for index in range(32) ] self._encoder = [ self._dial[index] for index in range(12) ] self._key_matrix = ButtonMatrixElement() button_row = [] for column in range(16): button_row.append(self._key[16 + column]) self._key_matrix.add_row(tuple(button_row)) def _setup_ohmmod(self): self._host = MonomodComponent(self) self._host.name = 'Monomod_Host' self.hosts = [self._host] self._hosts = [self._host] for index in range(6): self._client[index] = MonoClient(self, index) self._client[index].name = 'Client_' + str(index) self._client[index]._device_component.set_parameter_controls(tuple([ self._dial[num] for num in range(12) ])) self._client[index]._control_defs = {'dials': self._dial_matrix, 'buttons': self._dial_button_matrix, 'grid': self._mod_matrix, 'keys': self._key, 'knobs': [ self._dial[num + 12] for num in range(4) ]} self._host._active_client = self._client[0] self._host._active_client._is_active = True self._host.connect_to_clients(self) def _setup_switchboard(self): self._switchboard = SwitchboardElement(self, self._client) self._switchboard.name = 'Switchboard' def _setup_modes(self): self._shift_mode = ShiftModeComponent(self) self._shift_mode.name = 'Shift_Mode' self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r, self._livid) self._scale_mode = ScaleModeComponent(self) self._scale_mode.name = 'Scale_Mode' self._octave_mode = OctaveModeComponent(self) self._octave_mode.name = 'Octave_Mode' self._modNum = ModNumModeComponent(self, self.modNum_update) self._modNum.name = 'Mod_Number' self._modNum.set_mode = self._modNum_set_mode(self._modNum) self._modNum.set_mode_buttons([ self._menu[index] for index in range(6) ]) def _modNum_set_mode(self, modNum): def set_mode(mode): if modNum._is_enabled == True: assert isinstance(mode, int) assert (mode in range(modNum.number_of_modes())) if (modNum._mode_index != mode): modNum._mode_index = mode modNum.update() return set_mode def _setup_transport_control(self): self._transport = TransportComponent() self._transport.name = 'Transport' def _setup_mixer_control(self): global mixer is_momentary = True self._num_tracks = 7 mixer = SpecialMixerComponent(7, 0, True, False) mixer.name = 'Mixer' self._mixer = mixer for index in range(7): mixer.channel_strip(index).set_volume_control(self._fader[index]) for index in range(7): mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index) mixer.track_eq(index).name = 'Mixer_EQ_' + str(index) mixer.channel_strip(index)._invert_mute_feedback = True self.song().view.selected_track = mixer.channel_strip(0)._track def _setup_session_control(self): global session is_momentary = True num_tracks = 7 num_scenes = 5 session = SessionComponent(num_tracks, num_scenes) session.name = 'Session' self._session = session session.set_offsets(0, 0) self._scene = [ None for index in range(6) ] for row in range(num_scenes): self._scene[row] = session.scene(row) self._scene[row].name = 'Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_' + str(row) session.set_mixer(self._mixer) session.set_show_highlight(True) self._session_zoom = SessionZoomingComponent(session) self._session_zoom.name = 'Session_Overview' self.set_highlighting_session_component(self._session) def _assign_session_colors(self): self.log_message('assign session colors') num_tracks = 7 num_scenes = 5 self._session.set_stop_track_clip_value(STOP_CLIP_COLOR[self._rgb]) for row in range(num_scenes): for column in range(num_tracks): self._scene[row].clip_slot(column).set_triggered_to_play_value(CLIP_TRIGD_TO_PLAY_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_triggered_to_record_value(CLIP_TRIGD_TO_RECORD_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_stopped_value(CLIP_STOPPED_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_recording_value(CLIP_RECORDING_COLOR[self._rgb]) self._session_zoom.set_stopped_value(ZOOM_STOPPED_COLOR[self._rgb]) self._session_zoom.set_playing_value(ZOOM_PLAYING_COLOR[self._rgb]) self._session_zoom.set_selected_value(ZOOM_SELECTED_COLOR[self._rgb]) for row in range(8): for column in range(8): self._grid[column][row].set_force_next_value() self._session.on_scene_list_changed() self._shift_mode.update() def _setup_device_control(self): self._device = DeviceComponent() self._device.name = 'Device_Component' self.set_device_component(self._device) self._device_navigator = DetailViewControllerComponent() self._device_navigator.name = 'Device_Navigator' self._device_selection_follows_track_selection = FOLLOW def device_follows_track(self, val): self._device_selection_follows_track_selection = val == 1 return self def _setup_crossfader(self): self._mixer.set_crossfader_control(self._crossfader) def disconnect(self): """clean things up on disconnect""" self.song().view.remove_selected_track_listener(self._update_selected_device) self.log_message(time.strftime('%d.%m.%Y %H:%M:%S', time.localtime()) + '--------------= OhmModes log closed =--------------') ControlSurface.disconnect(self) def _get_num_tracks(self): return self.num_tracks def flash(self): for row in range(8): if self._button[row]._flash_state > 0: self._button[row].flash(self._timer) for column in range(8): button = self._grid[column][row] if button._flash_state > 0: button.flash(self._timer) 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 deassign_matrix(self): with self.component_guard(): self._host._set_knobs(None) self._host._set_button_matrix(None) self._host.set_enabled(False) self._modNum.set_enabled(False) self.assign_alternate_mappings(0) self._scale_mode.set_mode_buttons(None) self._scale_mode.set_enabled(False) self._octave_mode.set_mode_buttons(None) self._octave_mode.set_enabled(False) self._session_zoom.set_enabled(False) self._session_zoom.set_nav_buttons(None, None, None, None) self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) self._transport.set_enabled(False) for column in range(4): self._mixer.track_eq(column)._gain_controls = None self._mixer.track_eq(column).set_enabled(False) for column in range(7): self._mixer.channel_strip(column).set_crossfade_toggle(None) self._mixer.channel_strip(column).set_mute_button(None) self._mixer.channel_strip(column).set_solo_button(None) self._mixer.channel_strip(column).set_arm_button(None) self._mixer.channel_strip(column).set_send_controls(None) self._mixer.channel_strip(column).set_pan_control(None) self._mixer.track_eq(column).set_enabled(False) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(None) """for column in range(8): self._button[column]._on_value = SELECT_COLOR[self._rgb] for row in range(8): self._grid[column][row].set_enabled(True) self._grid[column][row].release_parameter() self._grid[column][row].use_default_message() self._grid[column][row].set_on_off_values(127, 0) self._grid[column][row].send_value(0, True)""" for column in range(8): self._button[column]._on_value = SELECT_COLOR[self._rgb] for row in range(8): #self._grid[column][row].set_channel(0) self._grid[column][row].release_parameter() self._grid[column][row].use_default_message() self._grid[column][row].set_enabled(True) self._grid[column][row].send_value(0, True) self._grid[column][row]._on_value = 127 self._grid[column][row]._off_value = 0 self._grid[column][row].force_next_send() for index in range(6): self._menu[index]._on_value = 127 self._menu[index]._off_value = 0 for index in range(16): self._dial[index].use_default_message() self._dial[index].release_parameter() self._device.set_parameter_controls(None) self._device.set_enabled(False) self._device_navigator.set_enabled(False) self._mixer.update() self._matrix.reset() self.request_rebuild_midi_map() def _assign_page_constants(self): with self.component_guard(): self._session_zoom.set_zoom_button(self._grid[7][7]) self._session_zoom.set_button_matrix(self._matrix) for column in range(7): self._mixer.channel_strip(column).set_select_button(self._button[column]) self._mixer.channel_strip(column).set_volume_control(self._fader[column]) self._mixer.master_strip().set_volume_control(self._fader[7]) self._mixer.master_strip().set_select_button(self._button[7]) self._mixer.set_prehear_volume_control(self._dial[15]) self._transport.set_play_button(self._menu[0]) self._menu[0].send_value(PLAY_COLOR[self._rgb], True) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._transport.set_stop_button(self._menu[1]) self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._menu[1].send_value(STOP_COLOR[self._rgb], True) self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[4]) def assign_page_0(self): with self.component_guard(): self._backlight_type = 'static' self._session_zoom.set_enabled(True) for column in range(7): self._grid[column][5]._on_value = MUTE_COLOR[self._rgb] self._mixer.channel_strip(column).set_mute_button(self._grid[column][5]) self._grid[column][6]._on_value = SOLO_COLOR[self._rgb] self._mixer.channel_strip(column).set_solo_button(self._grid[column][6]) self._grid[column][7]._on_value = ARM_COLOR[self._rgb] self._mixer.channel_strip(column).set_arm_button(self._grid[column][7]) self._mixer.channel_strip(column).set_pan_control(self._dial[column + 8]) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) for column in range(4): self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column], self._dial[column + 4]])) for index in range(5): self._grid[7][index]._off_value = SCENE_LAUNCH_COLOR[self._rgb] self._scene[index].set_launch_button(self._grid[7][index]) self._grid[7][index].set_force_next_value() self._grid[7][index].turn_off() for index in range(4): self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb] self._session.set_track_bank_buttons(self._menu[4], self._menu[3]) self._session.set_scene_bank_buttons(self._menu[5], self._menu[2]) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) #self._mixer.update_all() self.request_rebuild_midi_map() #self.log_message('assign_page_0') def assign_page_1(self): with self.component_guard(): self._backlight_type = 'pulse' self._session_zoom.set_enabled(False) for column in range(4): for row in range(4): self._grid[column][row].send_value(DRUM_COLOR[self._rgb], True) self._grid[column + 4][row].send_value(BASS_COLOR[self._rgb], True) self._grid[column][row].set_enabled(False) self._grid[column][row]._msg_channel = PAGE1_DRUM_CHANNEL self._grid[column][row].set_identifier(PAGE1_DRUM_MAP[column][row]) self._grid[column + 4][row].set_enabled(False) self._grid[column + 4][row]._msg_channel = PAGE1_BASS_CHANNEL self._grid[column + 4][row].set_identifier(PAGE1_BASS_MAP[column][row]) scale_mode_buttons = [] for column in range(8): for row in range(3): self._grid[column][row + 4].set_enabled(False) self._grid[column][row + 4].send_value(KEYS_COLOR[self._rgb], True) self._grid[column][row + 4]._msg_channel = PAGE1_KEYS_CHANNEL self._grid[column][row + 4].set_identifier(int(PAGE1_KEYS_MAP[column][row]) + int(PAGE1_MODES_MAP[self._scale_mode._mode_index][column]) + int(self._octave_mode._mode_index * 12)) for row in range(1): scale_mode_buttons.append(self._grid[column][7]) self._scale_mode.set_mode_buttons(tuple(scale_mode_buttons)) self._scale_mode.set_enabled(True) self._octave_mode.set_mode_buttons(tuple([self._menu[5], self._menu[2]])) self._octave_mode.set_enabled(True) for column in range(7): self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column + 8]])) self._mixer.channel_strip(column).set_arm_button(self._button[column]) self._device.set_enabled(True) device_param_controls = [] for index in range(8): device_param_controls.append(self._dial[index]) self._device.set_parameter_controls(tuple(device_param_controls)) self._menu[0]._on_value = PLAY_COLOR[self._rgb] for index in range(4): self._menu[2 + index]._on_value = DEVICE_NAV_COLOR[self._rgb] self._device_navigator.set_enabled(True) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) self.request_rebuild_midi_map() def assign_page_2(self): with self.component_guard(): self._backlight_type = 'up' self._session_zoom.set_enabled(True) for column in range(7): self._grid[column][5]._on_value = MUTE_COLOR[self._rgb] self._mixer.channel_strip(column).set_mute_button(self._grid[column][5]) self._grid[column][6]._on_value = CROSSFADE_ASSIGN_COLOR[self._rgb] self._mixer.channel_strip(column).set_crossfade_toggle(self._grid[column][6]) self._grid[column][7]._msg_channel = 2 self._grid[column][7].set_identifier(column) self._grid[column][7].reset() self._grid[column][7].set_enabled(False) self._grid[column][7].send_value(4, True) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) for row in range(5): self._grid[7][row]._off_value = SCENE_LAUNCH_COLOR[self._rgb] self._scene[row].set_launch_button(self._grid[7][row]) self._grid[7][row].set_force_next_value() self._grid[7][row].turn_off() for column in range(4): self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]])) self._mixer.track_eq(column).set_enabled(True) for column in range(3): self._mixer.channel_strip(column + 4).set_pan_control(self._dial[column + 12]) for index in range(4): self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb] self._session.set_track_bank_buttons(self._menu[4], self._menu[3]) self._session.set_scene_bank_buttons(self._menu[5], self._menu[2]) self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]]) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) #self._mixer.update() self.request_rebuild_midi_map() def assign_mod(self): with self.component_guard(): self.deassign_matrix() self._host.set_enabled(True) self._modNum.set_enabled(True) self._host._set_dial_matrix(self._dial_matrix, self._dial_button_matrix) self._host._set_button_matrix(self._mod_matrix) self._host._set_key_buttons(tuple(self._key)) if not self._host._active_client.is_connected(): self.assign_alternate_mappings(self._modNum._mode_index + 1) def modNum_update(self): if self._modNum._is_enabled == True: self.assign_alternate_mappings(0) self._host._select_client(int(self._modNum._mode_index)) self._host.display_active_client() if not self._host._active_client.is_connected(): self.assign_alternate_mappings(self._modNum._mode_index + 1) for button in self._modNum._modes_buttons: if self._modNum._mode_index == self._modNum._modes_buttons.index(button): button.send_value(1) else: button.send_value(self._client[self._modNum._modes_buttons.index(button)]._mod_color) def assign_alternate_mappings(self, chan): for column in range(8): for row in range(8): self._grid[column][row].set_channel(chan) for knob in self._encoder: knob.set_channel(chan) knob.set_enabled(chan is 0) self.request_rebuild_midi_map() def display_mod_colors(self): pass def _update_selected_device(self): if self._device_selection_follows_track_selection is True: track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self.set_appointed_device(device_to_select) self.request_rebuild_midi_map() def handle_sysex(self, midi_bytes): if len(midi_bytes) > 10: if midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 7]): self.log_message(str('>>>color detected')) self._rgb = 0 elif midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 2]): self.log_message(str('>>>mono detected')) self._rgb = 1 self._assign_session_colors() def to_encoder(self, num, val): rv = int(val * 127) self._device._parameter_controls[num].receive_value(rv) p = self._device._parameter_controls[num]._parameter_to_map_to newval = val * (p.max - p.min) + p.min p.value = newval def set_local_ring_control(self, val = 1): self._local_ring_control = val != 0 def set_absolute_mode(self, val = 1): self._absolute_mode = val != 0 def send_ring_leds(self): """if self._host._is_enabled == True: leds = [240, 0, 1, 97, 8, 31] for index in range(12): wheel = self._encoder[index] bytes = wheel._get_ring() leds.append(bytes[0]) leds.append(int(bytes[1]) + int(bytes[2])) leds.append(247) self._send_midi(tuple(leds))""" pass def _set_tempo_buttons(self, buttons): if self._tempo_buttons != None: self._tempo_buttons[0].remove_value_listener(self._tempo_value) self._tempo_buttons[1].remove_value_listener(self._tempo_value) self._tempo_buttons = buttons if buttons != None: for button in buttons: assert isinstance(button, FlashingButtonElement) self._tempo_buttons[0].set_on_off_values(4, 0) self._tempo_buttons[0].add_value_listener(self._tempo_value, True) self._tempo_buttons[1].set_on_off_values(4, 0) self._tempo_buttons[1].add_value_listener(self._tempo_value, True) self._tempo_buttons[0].turn_on() self._tempo_buttons[1].turn_on() def _tempo_value(self, value, sender): if value > 0 and self._tempo_buttons.index(sender) == 0: self.song().tempo = round(min(self.song().tempo + 1, 999)) elif value > 0 and self._tempo_buttons.index(sender) == 1: self.song().tempo = round(max(self.song().tempo - 1, 20)) def generate_strip_string(self, display_string): NUM_CHARS_PER_DISPLAY_STRIP = 12 if not display_string: return ' ' * NUM_CHARS_PER_DISPLAY_STRIP if len(display_string.strip()) > NUM_CHARS_PER_DISPLAY_STRIP - 1 and display_string.endswith('dB') and display_string.find('.') != -1: display_string = display_string[:-2] if len(display_string) > NUM_CHARS_PER_DISPLAY_STRIP - 1: for um in [' ', 'i', 'o', 'u', 'e', 'a']: while len(display_string) > NUM_CHARS_PER_DISPLAY_STRIP - 1 and display_string.rfind(um, 1) != -1: um_pos = display_string.rfind(um, 1) display_string = display_string[:um_pos] + display_string[um_pos + 1:] else: display_string = display_string.center(NUM_CHARS_PER_DISPLAY_STRIP - 1) ret = u'' for i in range(NUM_CHARS_PER_DISPLAY_STRIP - 1): if ord(display_string[i]) > 127 or ord(display_string[i]) < 0: ret += ' ' else: ret += display_string[i] ret += ' ' return ret def notification_to_bridge(self, name, value, sender): if isinstance(sender, tuple([MonoEncoderElement2, CodecEncoderElement])): self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name))) self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value))) 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) def get_clip_names(self): clip_names = [] for scene in self._session._scenes: for clip_slot in scene._clip_slots: if clip_slot.has_clip() is True: clip_names.append(clip_slot._clip_slot) return clip_slot._clip_slot return clip_names def shift_update(self): pass
class Launchkey_MK2(OptimizedControlSurface): identity_request_delay = 0.5 def __init__(self, c_instance, *a, **k): super(Launchkey_MK2, self).__init__(c_instance=c_instance, *a, **k) self._is_25_key_model = False self._is_in_control_on = True 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(xrange(21, 29)) ]]) self._top_pad_row = ButtonMatrixElement(rows=[[ make_button(identifier, name='Pad_0_%d' % (index,)) for index, identifier in enumerate(xrange(96, 104)) ]]) self._bottom_pad_row_raw = [ make_button(identifier, name='Pad_1_%d' % (index,)) for index, identifier in enumerate(xrange(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(xrange(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(xrange(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 xrange(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(CLIP_COLOR_TABLE, 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 xrange(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 xrange(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() self.on_identified() 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._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 Launchpad_Pro_Custom(IdentifiableControlSurface, OptimizedControlSurface): identity_request = consts.SYSEX_IDENTITY_REQUEST def __init__(self, c_instance, *a, **k): product_id_bytes = consts.MANUFACTURER_ID + consts.DEVICE_CODE super(Launchpad_Pro_Custom, self).__init__(c_instance=c_instance, product_id_bytes=product_id_bytes, *a, **k) self._challenge = Live.Application.get_random_int( 0, 400000000) & 2139062143 with self.component_guard(): self._skin = make_default_skin() with inject(skin=const(self._skin)).everywhere(): self._midimap = MidiMap() self._target_track_component = TargetTrackComponent( name='Target_Track') self._create_background() self._create_global_component() self._last_sent_mode_byte = None with inject(layout_setup=const(self._layout_setup), should_arm=const(self._should_arm_track)).everywhere(): self._create_session() self._create_arrangement() self._create_recording() self._create_actions() self._create_drums() self._create_mixer() self._create_device() self._create_modes() # self._create_user() self._create_arrangement_transport() self._on_session_record_changed.subject = self.song() self.set_device_component(self._device) self._on_session_record_changed() return def disconnect(self): self._send_midi(consts.TURN_OFF_LEDS) self._send_midi(consts.QUIT_MESSAGE) super(Launchpad_Pro_Custom, self).disconnect() def _create_background(self): self._modifier_background_component = ModifierBackgroundComponent( name='Background_Component', is_enabled=False, layer=Layer(shift_button=self._midimap['Shift_Button'])) self._shifted_background = BackgroundComponent( name='No_Op_Shifted_Buttons', is_enabled=False, layer=Layer( click_bitton=self._midimap.with_shift('Click_Button'), delete_button=self._midimap.with_shift('Delete_Button'), duplicate_button=self._midimap.with_shift('Duplicate_Button'), double_button=self._midimap.with_shift('Double_Loop_Button'), session_record_button=self._midimap.with_shift( 'Session_Record_Button'))) def _create_global_component(self): self._actions_component = ActionsComponent( name='Global_Actions', is_enabled=False, layer=Layer(undo_button=self._midimap['Undo_Button'], redo_button=self._midimap.with_shift('Undo_Button'), metronome_button=self._midimap['Click_Button'], quantization_on_button=self._midimap.with_shift( 'Quantize_Button'))) def _create_session(self): self._session = SessionComponent( NUM_TRACKS, NUM_SCENES, auto_name=True, is_enabled=False, enable_skinning=True, layer=Layer( track_bank_left_button=self._midimap['Arrow_Left_Button'], track_bank_right_button=self._midimap['Arrow_Right_Button'], scene_bank_up_button=self._midimap['Arrow_Up_Button'], scene_bank_down_button=self._midimap['Arrow_Down_Button'])) self._session.set_enabled(True) self._session.set_rgb_mode(LIVE_COLORS_TO_MIDI_VALUES, RGB_COLOR_TABLE) SpecialClipSlotComponent.quantization_component = self._actions_component for scene_index in xrange(NUM_SCENES): scene = self._session.scene(scene_index) scene.layer = Layer( select_button=self._midimap['Shift_Button'], delete_button=self._midimap['Delete_Button'], duplicate_button=self._midimap['Duplicate_Button']) for track_index in xrange(NUM_TRACKS): slot = scene.clip_slot(track_index) slot.layer = Layer( select_button=self._midimap['Shift_Button'], delete_button=self._midimap['Delete_Button'], duplicate_button=self._midimap['Duplicate_Button'], double_loop_button=self._midimap['Double_Loop_Button'], quantize_button=self._midimap['Quantize_Button']) self._session_zoom = SessionZoomingComponent(self._session, name='Session_Overview', is_enabled=True, enable_skinning=True) def _create_arrangement(self): self._arrangement = SpecialArrangementComponent( NUM_TRACKS, NUM_SCENES, auto_name=True, is_enabled=False, enable_skinning=True, layer=Layer( track_bank_up_button=self._midimap['Arrow_Up_Button'], track_bank_down_button=self._midimap['Arrow_Down_Button'], quantize_button=self._midimap['Quantize_Button'])) self._arrangement.set_enabled(True) # self._arrangement.set_rgb_mode(LIVE_COLORS_TO_MIDI_VALUES, RGB_COLOR_TABLE) def _create_recording(self): self._session_record = SpecialSessionRecordingComponent( self._target_track_component, name='Session_Recording', is_enabled=False, layer=Layer(record_button=self._midimap['Session_Record_Button'])) def _create_arrangement_transport(self): self._transport = TransportComponent(name='Transport', is_enabled=False, play_toggle_model_transform=False) self._transport.layer = Layer( play_button=self._midimap['Scene_Launch_Button_Matrix_Raw'][0][7], \ stop_button=self._midimap['Scene_Launch_Button_Matrix_Raw'][0][6], \ loop_button=self._midimap['Scene_Launch_Button_Matrix_Raw'][0][5], \ record_button=self._midimap['Session_Record_Button'] \ ) def _create_actions(self): self._clip_actions_component = ClipActionsComponent( self._target_track_component, name='Clip_Actions', is_enabled=False, layer=Layer(duplicate_button=self._midimap['Duplicate_Button'], double_button=self._midimap['Double_Loop_Button'], quantize_button=self._midimap['Quantize_Button'])) ClipActionsComponent.quantization_component = self._actions_component def _create_drums(self): self._drum_group_finder = DrumGroupFinderComponent( self._target_track_component, name='Drum_Group_Finder', is_enabled=False, layer=None) self._on_drum_group_changed.subject = self._drum_group_finder self._drum_group_finder.set_enabled(True) self._drum_group = DrumGroupComponent( self._clip_actions_component, name='Drum_Group_Control', translation_channel=consts.DR_MAP_CHANNEL) self._drum_group.set_enabled(True) return def _create_mixer(self): self._mixer = SpecialMixerComponent(NUM_TRACKS, auto_name=True, is_enabled=True, invert_mute_feedback=True) self._mixer.name = 'Mixer_Control' self._session.set_mixer(self._mixer) # self._arrangement.set_mixer(self._mixer) def _create_device(self): self._device = SpecialDeviceComponent( name='Device_Control', is_enabled=False, device_selection_follows_track_selection=True) self._device_navigation = DeviceNavigationComponent( name='Device_Navigation') self._device_background = BackgroundComponent( name='Device_Background_Component') def _setup_drum_group(self): self._drum_group.set_drum_group_device( self._drum_group_finder.drum_group) def _create_translation(self, comp_name, channel, button_layer, should_enable=True, should_reset=True): translation_component = TranslationComponent( name=comp_name, translated_channel=channel, should_enable=should_enable, should_reset=should_reset, is_enabled=False, layer=button_layer) setattr(self, '_' + comp_name.lower(), translation_component) return translation_component def _create_modes(self): self._modes = ModesComponent(name='Launchpad_Modes', is_enabled=False) self._session_layer_mode = AddLayerMode( self._session, Layer(scene_launch_buttons=self. _midimap['Scene_Launch_Button_Matrix'], clip_launch_buttons=self._midimap['Main_Button_Matrix'], delete_button=self._midimap['Delete_Button'], duplicate_button=self._midimap['Duplicate_Button'], double_button=self._midimap['Double_Loop_Button'], quantize_button=self._midimap['Quantize_Button'])) # self._arrangement_layer_mode = AddLayerMode(self._arrangement, Layer(transport_buttons=self._midimap['Scene_Launch_Button_Matrix'], track_buttons=self._midimap['Main_Button_Matrix'], quantize_button=self._midimap['Quantize_Button'])) action_button_background = BackgroundComponent(name='No_Op_Buttons') self._action_button_background_layer_mode = LayerMode( action_button_background, Layer(delete_button=self._midimap['Delete_Button'], quantize_button=self._midimap['Quantize_Button'], duplicate_button=self._midimap['Duplicate_Button'], double_button=self._midimap['Double_Loop_Button'])) self._clip_delete_layer_mode = AddLayerMode( self._clip_actions_component, layer=Layer(delete_button=self._midimap['Delete_Button'])) self._create_session_zooming_modes() self._create_session_mode() self._create_note_modes() self._create_device_mode() # self._create_user_mode() self._create_arrangement_mode() self._create_record_arm_mode() self._create_track_select_mode() self._create_mute_mode() self._create_solo_mode() self._create_volume_mode() self._create_pan_mode() self._create_sends_mode() self._create_stop_clips_mode() self._modes.layer = Layer( session_mode_button=self._midimap['Session_Mode_Button'], note_mode_button=self._midimap['Note_Mode_Button'], device_mode_button=self._midimap['Device_Mode_Button'], arrangement_mode_button=self._midimap['User_Mode_Button'], record_arm_mode_button=self._midimap['Record_Arm_Mode_Button'], track_select_mode_button=self._midimap['Track_Select_Mode_Button'], mute_mode_button=self._midimap['Mute_Mode_Button'], solo_mode_button=self._midimap['Solo_Mode_Button'], volume_mode_button=self._midimap['Volume_Mode_Button'], pan_mode_button=self._midimap['Pan_Mode_Button'], sends_mode_button=self._midimap['Sends_Mode_Button'], stop_clip_mode_button=self._midimap['Stop_Clip_Mode_Button']) self._modes.selected_mode = 'session_mode' self._on_layout_changed.subject = self._modes self._create_view_control_component() def _create_session_zooming_modes(self): session_zoom_layer = Layer( button_matrix=self._midimap['Main_Button_Matrix'], nav_left_button=self._midimap['Arrow_Left_Button'], nav_right_button=self._midimap['Arrow_Right_Button'], nav_up_button=self._midimap['Arrow_Up_Button'], nav_down_button=self._midimap['Arrow_Down_Button']) session_zooming_layer_mode = LayerMode(self._session_zoom, session_zoom_layer) self._session_zooming_manager = SessionZoomingManagerComponent( self._modes, is_enabled=False) session_zooming_button_layer_mode = LayerMode( self._session_zooming_manager, Layer(session_zooming_button=self._midimap['Session_Mode_Button'])) self._prioritized_session_zooming_button_layer_mode = LayerMode( self._session_zooming_manager, Layer(session_zooming_button=self._midimap['Session_Mode_Button'], priority=1)) self._session_zooming_background = BackgroundComponent( name='Session_Zooming_Background') session_zooming_background_layer_mode = LayerMode( self._session_zooming_background, Layer(scene_launch_buttons=self. _midimap['Scene_Launch_Button_Matrix'], delete_button=self._midimap['Delete_Button'], quantize_button=self._midimap['Quantize_Button'], duplicate_button=self._midimap['Duplicate_Button'], double_loop_button=self._midimap['Double_Loop_Button'])) self._modes.add_mode('session_zooming_mode', [ self._session_zooming_manager, session_zooming_button_layer_mode, session_zooming_layer_mode, session_zooming_background_layer_mode ]) self._modes.add_mode('prioritized_session_zooming_mode', [ partial(self._layout_switch, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, session_zooming_layer_mode, session_zooming_background_layer_mode, self.update ]) def _create_session_mode(self): self._modes.add_mode( 'session_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, self._session.update_navigation_buttons ], behaviour=CancelingReenterBehaviour('session_zooming_mode')) def _create_note_modes(self): note_mode_matrix_translation = self._create_translation( 'Note_Mode_Matrix_Translation', consts.CHROM_MAP_CHANNEL, Layer(button_matrix=self._midimap['Main_Button_Matrix'], note_button_matrix=self._midimap['Note_Button_Matrix'], drum_matrix=self._midimap['Drum_Button_Matrix'], mixer_button_matrix=self._midimap['Mixer_Button_Matrix']), should_enable=False) note_mode_scene_launch_translation = self._create_translation( 'Note_Mode_Scene_Launch_Translation', consts.CHROM_MAP_CHANNEL, Layer(scene_launch_buttons=self. _midimap['Scene_Launch_Button_Matrix'])) scale_setup_mode_button_lighting = LedLightingComponent( name='LED_Lighting_Component', is_enabled=False, layer=Layer(button=self._midimap.with_shift('Note_Mode_Button'))) drum_mode_note_matrix_translation = self._create_translation( 'Drum_Mode_Note_Button_Translation', 0, Layer(note_button_matrix=self._midimap['Note_Button_Matrix']), should_enable=False, should_reset=False) drum_group_layer_mode = LayerMode( self._drum_group, layer=Layer( scroll_up_button=self._midimap['Arrow_Left_Button'], scroll_down_button=self._midimap['Arrow_Right_Button'], scroll_page_up_button=self._midimap['Arrow_Up_Button'], scroll_page_down_button=self._midimap['Arrow_Down_Button'], drum_matrix=self._midimap['Drum_Button_Matrix'], select_button=self._midimap['Shift_Button'], delete_button=self._midimap['Delete_Button'])) self._note_modes = SpecialModesComponent(name='Note_Modes') self._note_modes.add_mode('chromatic_mode', [ partial(self._layout_setup, consts.NOTE_LAYOUT_SYSEX_BYTE), self._clip_delete_layer_mode, note_mode_matrix_translation, scale_setup_mode_button_lighting ]) self._note_modes.add_mode('drum_mode', [ partial(self._layout_setup, consts.DRUM_LAYOUT_SYSEX_BYTE), self._setup_drum_group, drum_group_layer_mode, drum_mode_note_matrix_translation ]) self._note_modes.add_mode('audio_mode', [ partial(self._layout_setup, consts.AUDIO_LAYOUT_SYSEX_BYTE), self._clip_delete_layer_mode ]) self._note_modes.set_enabled(False) self._modes.add_mode('note_mode', [ note_mode_scene_launch_translation, self._note_modes, self._select_note_mode, self._select_target_track, self._clip_actions_component, self._show_playing_clip, self._set_clip_actions_type ], behaviour=ReenterBehaviour( self.toggle_detail_view)) self._session_record.set_modes_component(self._modes) self._session_record.set_note_mode_name('note_mode') def _create_device_mode(self): device_mode_scene_launch_translation = self._create_translation( 'Device_Mode_Scene_Launch_Translation', consts.DEVICE_MAP_CHANNEL, Layer(scene_launch_buttons=self. _midimap['Scene_Launch_Button_Matrix'])) device_layer_mode = LayerMode( self._device, layer=Layer( parameter_controls=self._midimap['Slider_Button_Matrix'])) device_nav_layer_mode = LayerMode( self._device_navigation, layer=Layer( device_nav_left_button=self._midimap['Arrow_Left_Button'], device_nav_right_button=self._midimap['Arrow_Right_Button'])) device_background_layer_mode = LayerMode( self._device_background, layer=Layer(arrow_up_button=self._midimap['Arrow_Up_Button'], arrow_down_button=self._midimap['Arrow_Down_Button'])) self._modes.add_mode('device_mode', [ partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), self._device, device_layer_mode, device_nav_layer_mode, device_background_layer_mode, self._clip_actions_component, self._clip_delete_layer_mode, device_mode_scene_launch_translation, self._show_playing_clip, self._set_clip_actions_type ], behaviour=ReenterBehaviour( self.toggle_detail_view)) # def _create_user_mode(self): # self._modes.add_mode('user_mode', [partial(self._layout_setup, consts.USER_LAYOUT_SYSEX_BYTE)]) def _create_arrangement_mode(self): self._arrangement_mixer = SpecialMixerComponent( NUM_TRACKS, auto_name=True, is_enabled=True, invert_mute_feedback=True) self._arrangement_mixer.name = 'Arrangement_Mixer_Control' self._arrangement.set_mixer(self._arrangement_mixer) arrangement_mixer_layer_mode = LayerMode( self._arrangement_mixer, layer=Layer( track_select_buttons=self._midimap['Main_Button_Matrix']. submatrix[4, :], arm_buttons=self._midimap['Main_Button_Matrix'].submatrix[ 7, :], solo_buttons=self._midimap['Main_Button_Matrix'].submatrix[ 6, :], mute_buttons=self._midimap['Main_Button_Matrix'].submatrix[ 5, :])) # LHS_layer_mode = LayerMode( quantize_button=self._midimap['Quantize_Button'] ) self._modes.add_mode('arrangement_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), arrangement_mixer_layer_mode, self._arrangement.update_navigation_buttons ], behaviour=ReenterBehaviour( self.toggle_detail_view)) # self._arrangement_background = BackgroundComponent(name='Arrangement_Background') def _create_record_arm_mode(self): arm_layer_mode = LayerMode( self._mixer, layer=Layer(arm_buttons=self._midimap['Mixer_Button_Matrix'])) self._modes.add_mode('record_arm_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, arm_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour('session_mode')) def _create_track_select_mode(self): track_select_layer_mode = LayerMode( self._mixer, layer=Layer( track_select_buttons=self._midimap['Mixer_Button_Matrix'])) self._modes.add_mode('track_select_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, track_select_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour('session_mode')) def _create_mute_mode(self): mute_layer_mode = LayerMode( self._mixer, layer=Layer(mute_buttons=self._midimap['Mixer_Button_Matrix'])) self._modes.add_mode('mute_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, mute_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour('session_mode')) def _create_solo_mode(self): solo_layer_mode = LayerMode( self._mixer, layer=Layer(solo_buttons=self._midimap['Mixer_Button_Matrix'])) self._modes.add_mode('solo_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, solo_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour('session_mode')) def _create_volume_mode(self): volume_mode_scene_launch_translation = self._create_translation( 'Volume_Mode_Scene_Launch_Translation', consts.VOLUME_MAP_CHANNEL, Layer(scene_launch_buttons=self. _midimap['Scene_Launch_Button_Matrix'])) volume_layer_mode = LayerMode( self._mixer, layer=Layer(volume_controls=self._midimap['Slider_Button_Matrix'])) self._modes.add_mode('volume_mode', [ partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), volume_layer_mode, self._action_button_background_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, volume_mode_scene_launch_translation, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour('session_mode')) def _create_pan_mode(self): pan_mode_scene_launch_translation = self._create_translation( 'Pan_Mode_Scene_Launch_Translation', consts.PAN_MAP_CHANNEL, Layer(scene_launch_buttons=self. _midimap['Scene_Launch_Button_Matrix'])) pan_layer_mode = LayerMode( self._mixer, layer=Layer(pan_controls=self._midimap['Slider_Button_Matrix'])) self._modes.add_mode('pan_mode', [ partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), pan_layer_mode, self._action_button_background_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, pan_mode_scene_launch_translation, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour('session_mode')) def _create_sends_mode(self): send_layer_mode = LayerMode( self._mixer, layer=Layer(send_controls=self._midimap['Slider_Button_Matrix'], send_select_buttons=self. _midimap['Scene_Launch_Button_Matrix'])) self._modes.add_mode('sends_mode', [ partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), send_layer_mode, self._action_button_background_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour('session_mode')) def _create_stop_clips_mode(self): stop_layer_mode = AddLayerMode( self._session, Layer( stop_track_clip_buttons=self._midimap['Mixer_Button_Matrix'], stop_scene_clip_buttons=self. _midimap['Scene_Stop_Button_Matrix'], stop_all_clips_button=self._midimap['Stop_All_Clips_Button'])) self._modes.add_mode('stop_clip_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, stop_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour('session_mode')) def toggle_detail_view(self): view = self.application().view if view.is_view_visible('Detail'): if view.is_view_visible('Detail/DeviceChain'): view.show_view('Detail/Clip') else: view.show_view('Detail/DeviceChain') # def _create_user(self): # self._user_matrix_component = UserMatrixComponent(name='User_Matrix_Component', is_enabled=False, layer=Layer(user_button_matrix_ch_6=self._midimap['User_Button_Matrix_Ch_6'], user_button_matrix_ch_7=self._midimap['User_Button_Matrix_Ch_7'], user_button_matrix_ch_8=self._midimap['User_Button_Matrix_Ch_8'], user_button_matrix_ch_14=self._midimap['User_Button_Matrix_Ch_14'], user_button_matrix_ch_15=self._midimap['User_Button_Matrix_Ch_15'], user_button_matrix_ch_16=self._midimap['User_Button_Matrix_Ch_16'], user_left_side_button_matrix_ch_6=self._midimap['User_Left_Side_Button_Matrix_Ch_6'], user_left_side_button_matrix_ch_7=self._midimap['User_Left_Side_Button_Matrix_Ch_7'], user_left_side_button_matrix_ch_8=self._midimap['User_Left_Side_Button_Matrix_Ch_8'], user_left_side_button_matrix_ch_14=self._midimap['User_Left_Side_Button_Matrix_Ch_14'], user_left_side_button_matrix_ch_15=self._midimap['User_Left_Side_Button_Matrix_Ch_15'], user_left_side_button_matrix_ch_16=self._midimap['User_Left_Side_Button_Matrix_Ch_16'], user_right_side_button_matrix_ch_6=self._midimap['User_Right_Side_Button_Matrix_Ch_6'], user_right_side_button_matrix_ch_7=self._midimap['User_Right_Side_Button_Matrix_Ch_7'], user_right_side_button_matrix_ch_8=self._midimap['User_Right_Side_Button_Matrix_Ch_8'], user_right_side_button_matrix_ch_14=self._midimap['User_Right_Side_Button_Matrix_Ch_14'], user_right_side_button_matrix_ch_15=self._midimap['User_Right_Side_Button_Matrix_Ch_15'], user_right_side_button_matrix_ch_16=self._midimap['User_Right_Side_Button_Matrix_Ch_16'], user_bottom_button_matrix_ch_6=self._midimap['User_Bottom_Button_Matrix_Ch_6'], user_bottom_button_matrix_ch_7=self._midimap['User_Bottom_Button_Matrix_Ch_7'], user_bottom_button_matrix_ch_8=self._midimap['User_Bottom_Button_Matrix_Ch_8'], user_bottom_button_matrix_ch_14=self._midimap['User_Bottom_Button_Matrix_Ch_14'], user_bottom_button_matrix_ch_15=self._midimap['User_Bottom_Button_Matrix_Ch_15'], user_bottom_button_matrix_ch_16=self._midimap['User_Bottom_Button_Matrix_Ch_16'], user_arrow_button_matrix_ch_6=self._midimap['User_Arrow_Button_Matrix_Ch_6'], user_arrow_button_matrix_ch_7=self._midimap['User_Arrow_Button_Matrix_Ch_7'], user_arrow_button_matrix_ch_8=self._midimap['User_Arrow_Button_Matrix_Ch_8'], user_arrow_button_matrix_ch_14=self._midimap['User_Arrow_Button_Matrix_Ch_14'], user_arrow_button_matrix_ch_15=self._midimap['User_Arrow_Button_Matrix_Ch_15'], user_arrow_button_matrix_ch_16=self._midimap['User_Arrow_Button_Matrix_Ch_16'])) # self._user_matrix_component.set_enabled(True) def _create_view_control_component(self): return ViewControlComponent(name='View_Control') @subject_slot('drum_group') def _on_drum_group_changed(self): if self._note_modes.selected_mode == 'drum_mode': self._drum_group.set_drum_group_device( self._drum_group_finder.drum_group) if self._modes.selected_mode == 'note_mode': self._select_note_mode() else: self.release_controlled_track() self._update_note_mode_button( self._drum_group_finder.drum_group is not None) return def _select_note_mode(self): u""" Selects which note mode to use depending on the kind of current target track and its device chain. Will also select the target if specified. """ track = self._target_track_component.target_track drum_device = self._drum_group_finder.drum_group if track is None or track.is_foldable or track in self.song( ).return_tracks or track == self.song( ).master_track or track.is_frozen or track.has_audio_input: self._note_modes.selected_mode = 'audio_mode' else: if drum_device: self._note_modes.selected_mode = 'drum_mode' else: self._note_modes.selected_mode = 'chromatic_mode' self._modes.update() if self._note_modes.selected_mode == 'audio_mode': self.release_controlled_track() else: self.set_controlled_track( self._target_track_component.target_track) return def _select_target_track(self): track = self._target_track_component.target_track if track != self.song().view.selected_track: self.song().view.selected_track = track def _update_note_mode_button(self, focused_track_is_drum_track): button = self._midimap['Note_Mode_Button'] if focused_track_is_drum_track: button.default_states = { True: 'Mode.Drum.On', False: 'Mode.Drum.Off' } else: button.default_states = { True: 'Mode.Chromatic.On', False: 'Mode.Chromatic.Off' } button.reset_state() self._modes.update() def _show_playing_clip(self): track = None if self._use_sel_track(): track = self.song().view.selected_track else: track = self._target_track_component.target_track if track in self.song().tracks: slot_index = track.fired_slot_index if slot_index < 0: slot_index = track.playing_slot_index if slot_index >= 0: clip_slot = track.clip_slots[slot_index] self.song().view.highlighted_clip_slot = clip_slot return def _set_clip_actions_type(self): self._clip_actions_component.use_selected_track(self._use_sel_track()) self._clip_actions_component.update() def _use_sel_track(self): return self._modes.selected_mode == 'device_mode' def _should_arm_track(self): return self._modes.selected_mode == 'record_arm_mode' @subject_slot('selected_mode') def _on_layout_changed(self, mode): if mode == 'note_mode': self.set_controlled_track( self._target_track_component.target_track) else: self.release_controlled_track() self._session_record.set_enabled(mode != 'arrangement_mode') self._transport.set_enabled(mode == 'arrangement_mode') # Flip between arranement and session views if mode == 'arrangement_mode': self.application().view.focus_view('Arranger') if mode == 'session_mode': self.application().view.focus_view('Session') @subject_slot('session_record') def _on_session_record_changed(self): status = self.song().session_record feedback_color = int(self._skin['Instrument.FeedbackRecord'] if status else self._skin['Instrument.Feedback']) self._c_instance.set_feedback_velocity(feedback_color) def _clear_send_cache(self): with self.component_guard(): for control in self.controls: control.clear_send_cache() def _update_hardware(self): self._clear_send_cache() self.update() def _update_global_components(self): self._actions_component.update() self._session_record.update() self._modifier_background_component.update() def _layout_setup(self, mode): self._layout_switch(mode) self._clear_send_cache() self._update_global_components() def _layout_switch(self, mode): prefix = consts.SYSEX_STANDARD_PREFIX + consts.SYSEX_PARAM_BYTE_LAYOUT suffix = consts.SYSEX_STANDARD_SUFFIX self._send_midi(prefix + mode + suffix) self._last_sent_mode_byte = mode def port_settings_changed(self): self.set_highlighting_session_component(None) super(Launchpad_Pro_Custom, self).port_settings_changed() return def on_identified(self): self._send_challenge() def _send_challenge(self): challenge_bytes = [] for index in range(4): challenge_bytes.append(self._challenge >> 8 * index & 127) challenge = consts.CHALLENGE_PREFIX + tuple(challenge_bytes) + (247, ) self._send_midi(challenge) def _on_handshake_successful(self): self._do_send_midi(consts.LIVE_MODE_SWITCH_REQUEST) with self.component_guard(): self._modes.set_enabled(True) self._actions_component.set_enabled(True) self._session_record.set_enabled(True) self._modifier_background_component.set_enabled(True) self._shifted_background.set_enabled(True) self.release_controlled_track() self.set_feedback_channels(consts.FEEDBACK_CHANNELS) self._transport.set_enabled(False) if self._last_sent_mode_byte is not None: self._layout_setup(self._last_sent_mode_byte) self.set_highlighting_session_component(self._session) self.update() return def _is_challenge_response(self, midi_bytes): return len( midi_bytes ) == 10 and midi_bytes[:7] == consts.SYSEX_STANDARD_PREFIX + consts.SYSEX_CHALLENGE_RESPONSE_BYTE def _is_response_valid(self, midi_bytes): response = long(midi_bytes[7]) response += long(midi_bytes[8] << 8) return response == Live.Application.encrypt_challenge2(self._challenge) def handle_sysex(self, midi_bytes): if len(midi_bytes) < 7: pass else: if self._is_challenge_response( midi_bytes) and self._is_response_valid(midi_bytes): self._on_handshake_successful() else: if midi_bytes[ 6] == consts.SYSEX_STATUS_BYTE_LAYOUT and midi_bytes[ 7] == consts.NOTE_LAYOUT_SYSEX_BYTE[0]: self._update_hardware() else: if midi_bytes[6] in (consts.SYSEX_STATUS_BYTE_MODE, consts.SYSEX_STATUS_BYTE_LAYOUT): pass else: super(Launchpad_Pro_Custom, self).handle_sysex(midi_bytes)
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 Launchkey_MK2(OptimizedControlSurface): identity_request_delay = 0.5 def __init__(self, c_instance, *a, **k): super(Launchkey_MK2, self).__init__(c_instance=c_instance, *a, **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=u'Encoder_%d' % (index,)) for index, identifier in enumerate(xrange(21, 29)) ]]) self._top_pad_row = ButtonMatrixElement(rows=[[ make_button(identifier, name=u'Pad_0_%d' % (index,)) for index, identifier in enumerate(xrange(96, 104)) ]]) self._bottom_pad_row_raw = [ make_button(identifier, name=u'Pad_1_%d' % (index,)) for index, identifier in enumerate(xrange(112, 120)) ] self._bottom_pad_row = ButtonMatrixElement(rows=[self._bottom_pad_row_raw]) self._top_launch_button = make_button(104, name=u'Scene_Launch_Button') self._bottom_launch_button = make_button(120, name=u'Stop_All_Clips_Button') self._scene_up_button = make_button(112, MIDI_CC_TYPE, name=u'Scene_Up_Button') self._scene_down_button = make_button(113, MIDI_CC_TYPE, name=u'Scene_Down_Button') self._stop_button = make_button(114, MIDI_CC_TYPE, name=u'Stop_Button') self._play_button = make_button(115, MIDI_CC_TYPE, name=u'Play_Button') self._loop_button = make_button(116, MIDI_CC_TYPE, name=u'Loop_Button') self._record_button = make_button(117, MIDI_CC_TYPE, name=u'Record_Button') self._sliders = ButtonMatrixElement(rows=[[ make_slider(identifier, name=u'Slider_%d' % (index,)) for index, identifier in enumerate(xrange(41, 49)) ]]) self._master_slider = make_slider(7, name=u'Master_Slider') self._25_key_slider = make_slider(7, name=u'Slider', channel=0) self._mute_buttons_raw = [ make_button(identifier, MIDI_CC_TYPE, name=u'Mute_Button_%d' % (index,)) for index, identifier in enumerate(xrange(51, 59)) ] self._mute_buttons = ButtonMatrixElement(rows=[self._mute_buttons_raw]) self._master_button = make_button(59, MIDI_CC_TYPE, name=u'Master_Button') self._track_left_button = make_button(102, MIDI_CC_TYPE, name=u'Track_Left_Button') self._track_right_button = make_button(103, MIDI_CC_TYPE, name=u'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 xrange(consts.MAX_SENDS): setattr(self, u'_send_%d_button' % (index,), self._bottom_pad_row_raw[index + 2]) self._send_mode_buttons[u'send_%d_mode_button' % (index,)] = getattr(self, u'_send_%d_button' % (index,)) self._extended_mode_button = make_button(12, name=u'Dummy_Extended_Mode_Button') self._extended_mode_button.add_value_listener(nop) self._encoder_incontrol_button = make_button(13, is_momentary=False, name=u'Encoder_InControl_Button') self._encoder_incontrol_button.add_value_listener(nop) self._slider_incontrol_button = make_button(14, is_momentary=False, name=u'Fader_InControl_Button') self._slider_incontrol_button.add_value_listener(nop) self._pad_incontrol_button = make_button(15, is_momentary=False, name=u'Pad_InControl_Button') self._pad_incontrol_button.add_value_listener(self._update_pads) self._encoder_incontrol_button2 = make_button(16, name=u'Encoder_InControl_Button') self._pad_in_control_status_button = make_button(11, name=u'Dummy_InControl_Button') def _create_session(self): self._session = SessionComponent(name=u'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=u'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=u'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=u'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(u'mute_mode', mute_mode) self._mute_button_modes.add_mode(u'solo_mode', solo_mode, behaviour=CancellableBehaviour()) self._mute_button_modes.layer = Layer(solo_mode_button=self._master_button) self._mute_button_modes.selected_mode = u'mute_mode' self._mute_button_modes.set_enabled(True) def _create_device(self): self._device = DeviceComponent(name=u'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=u'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(u'device_mode', device_mode, is_enabled=True) self._encoder_modes.add_mode(u'pan_mode', [pan_mode, background_mode], is_enabled=True) for index in xrange(6): self._encoder_modes.add_mode(u'send_%d_mode' % (index,), [sends_mode, partial(self._set_send_index, index), background_mode], is_enabled=False) self._encoder_modes.selected_mode = u'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(u'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(u'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(u'value') def _update_pads(self, value): if value: self.update() @subject_slot(u'return_tracks') def _on_return_tracks_changed(self): num_sends = self._mixer.num_sends for index in xrange(6): self._encoder_modes.set_mode_enabled(u'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(u'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 = u'session_mode' self.update() def disconnect(self): self._extended_mode_button.turn_off() super(Launchkey_MK2, self).disconnect()
class APC_mini_custom(APC): # Connecting APC to ableton def _product_model_id_byte(self): return 40 def _update_hardware(self): self._send_midi((240, 126, 127, 6, 1, 247)) return def _on_identity_response(self, midi_bytes): super(APC_mini_custom, self)._on_identity_response(midi_bytes) def _send_dongle_challenge(self): pass def _on_handshake_successful(self): pass def print_message(self, message): self.log_message(message) self.show_message(message) def receive_midi(self, midi_bytes): self.print_message("Received " + str(midi_bytes)) super(APC_mini_custom, self).receive_midi(midi_bytes) def really_send_midi(self, midi_bytes): #self.print_message("Sending " + str(midi_bytes)) super(APC_mini_custom, self)._do_send_midi(midi_bytes) # Setting up def __init__(self, *a, **k): super(APC_mini_custom, self).__init__(*a, **k) disp.clearAll(self) #disp.splash(self) self.print_message("Initialized APC") self._skin = skins.make_skin() self._suppress_send_midi = False with self.component_guard(): self.setup() def setup(self): self.setupStarted = True self.mute = self.song().master_track.devices[1].parameters[10] self._create_controls() self._cue_control = self._setup_cue_control() self._omni_control = self._setup_omni_control() self._master_controls = self._setup_master_controls() self._misc_controls = self._setup_misc_control() self._setup_transport_control() def _create_controls(self): make_color_button = partial(make_button, skin=self._skin) self._matrix_buttons = [ make_color_button(0, i, name=b'Matrix_Button_%d' % i) for i in range(MATRIX_SIZE * MATRIX_SIZE) ] cue_rows = 3 self._cue_buttons = [ self._matrix_buttons[i] for r in range(cue_rows) for i in range(MATRIX_SIZE * (MATRIX_SIZE - (r + 1)), MATRIX_SIZE * (MATRIX_SIZE - r)) ] for button in self._cue_buttons: button._skin = skins.get_cue_button() self._instrument_buttons = [ self._matrix_buttons[i] for i in range(MATRIX_SIZE - 1) ] for button in self._instrument_buttons: button._skin = skins.get_instrument_button() self._omni_buttons = [ self._matrix_buttons[MATRIX_SIZE * 3 + i] for i in range(MATRIX_SIZE) ] for button in self._omni_buttons: button._skin = skins.get_omni_button() self._vertical_buttons = [ make_color_button(0, 82 + i, name="Vertical_Button_%d" % i) for i in range(MATRIX_SIZE) ] self._horizontal_buttons = [ make_color_button(0, 64 + i, name="Horizontal_Button_%d" % i) for i in range(MATRIX_SIZE) ] self._left_button = self._horizontal_buttons[2] self._right_button = self._horizontal_buttons[3] self._master_add_volume_control = make_slider( 0, 55, name=b'Master_Add_Volume_Control') self._master_sub_volume_control = make_slider( 0, 56, name=b'Master_Sub_Volume_Control') self._master_mute_control = self._horizontal_buttons[7] self._master_mute_control._skin = skins.get_mute_button() self._splash_button = self._vertical_buttons[0] def _setup_cue_control(self): cue_control = CueComponent(self, name=b'Cue_Point_Control', play_on_cue=True) cue_control.set_cue_buttons(self._cue_buttons) cue_control.set_instrument_buttons(self._instrument_buttons) cue_control.set_enabled(True) return cue_control def _setup_omni_control(self): omni_control = OmniComponent(self, name=b"Omni_Control") omni_control.set_buttons(self._omni_buttons) omni_control.set_enabled(True) return omni_control def _setup_master_controls(self): self._master_mute_control.add_value_listener( self._on_master_mute_changed) return self._master_mute_control def _on_master_mute_changed(self, value): if (value > 0): if (self.mute.value < .5): self.mute.value = 1 self._master_mute_control.set_light("On") else: self.mute.value = 0 self._master_mute_control.set_light("Off") def _setup_misc_control(self): self._splash_button.add_value_listener(self._on_splash) self.splashing = False return self._splash_button def _on_splash(self, value): if (value > 0): if (self.splashing): self.splashing = False disp.clearAll(self) self._cue_control.reset_lights() else: self.splashing = True disp.splash(self) def _setup_transport_control(self): self._transport_control = TransportComponent(name=b'Transport') self._transport_control.set_enabled(True)
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 __init__(self, *a, **k): super(MPK261MXLOOP, self).__init__(*a, **k) self.show_message("-----------------------= MPK261MXLOOP LOADING - maxcloutier13 says hi =----------------------------------------------------------") self.log_message("-----------------------= MPK261MXLOOP LOADING - maxcloutier13 says hi =----------------------------------------------------------") with self.component_guard(): midimap = MidiMap() #Sustain pedal 1 = Play/Record/Overdub switch for live looping self._LoopRecordButton = ButtonElement(True, MIDI_CC_TYPE, 0, 64) self._LoopRecordButton.add_value_listener(self._launch_clip, False) #Sustain pedal 2 = Sustain pour l'instant ;o) #self._LoopRecordButton = ButtonElement(True, MIDI_CC_TYPE, 0, 65) #Control up/down/left/right using the daw controls self._UpButton = ButtonElement(False, MIDI_CC_TYPE, 0, 88, name='UpButton') self._DownButton = ButtonElement(False, MIDI_CC_TYPE, 0, 89, name='DownButton') self._LeftButton = ButtonElement(False, MIDI_CC_TYPE, 0, 20, name='LeftButton') self._RightButton = ButtonElement(False, MIDI_CC_TYPE, 0, 21, name='RightButton') #Listeners for the functions self._UpButton.add_value_listener(self._move_up, False) self._DownButton.add_value_listener(self._move_down, False) self._LeftButton.add_value_listener(self._move_left, False) self._RightButton.add_value_listener(self._move_right, False) #Super crude manual init for the custom buttons and faders #Control Bank A - Channel 1 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- self._Encoder0 = EncoderElement(MIDI_CC_TYPE,1,22, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder0') self._Encoder1 = EncoderElement(MIDI_CC_TYPE,1,23, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder1') self._Encoder2 = EncoderElement(MIDI_CC_TYPE,1,24, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder2') self._Encoder3 = EncoderElement(MIDI_CC_TYPE,1,25, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder3') self._Encoder4 = EncoderElement(MIDI_CC_TYPE,1,26, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder4') self._Encoder5 = EncoderElement(MIDI_CC_TYPE,1,27, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder5') self._Encoder6 = EncoderElement(MIDI_CC_TYPE,1,28, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder6') self._Encoder7 = EncoderElement(MIDI_CC_TYPE,1,29, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder7') self._ArmButton0 = ButtonElement(False, MIDI_CC_TYPE, 0, 32, name='ArmButton0') self._ArmButton1 = ButtonElement(False, MIDI_CC_TYPE, 0, 33, name='ArmButton1') self._ArmButton2 = ButtonElement(False, MIDI_CC_TYPE, 0, 34, name='ArmButton2') self._ArmButton3 = ButtonElement(False, MIDI_CC_TYPE, 0, 35, name='ArmButton3') self._ArmButton4 = ButtonElement(False, MIDI_CC_TYPE, 0, 36, name='ArmButton4') self._ArmButton5 = ButtonElement(False, MIDI_CC_TYPE, 0, 37, name='ArmButton5') self._ArmButton6 = ButtonElement(False, MIDI_CC_TYPE, 0, 38, name='ArmButton6') self._ArmButton7 = ButtonElement(False, MIDI_CC_TYPE, 0, 39, name='ArmButton7') self._VolumeSlider0 = SliderElement(MIDI_CC_TYPE, 0, 12, name='VolumeSlider0') self._VolumeSlider1 = SliderElement(MIDI_CC_TYPE, 0, 13, name='VolumeSlider1') self._VolumeSlider2 = SliderElement(MIDI_CC_TYPE, 0, 14, name='VolumeSlider2') self._VolumeSlider3 = SliderElement(MIDI_CC_TYPE, 0, 15, name='VolumeSlider3') self._VolumeSlider4 = SliderElement(MIDI_CC_TYPE, 0, 16, name='VolumeSlider4') self._VolumeSlider5 = SliderElement(MIDI_CC_TYPE, 0, 17, name='VolumeSlider5') self._VolumeSlider6 = SliderElement(MIDI_CC_TYPE, 0, 18, name='VolumeSlider6') self._VolumeSlider7 = SliderElement(MIDI_CC_TYPE, 0, 19, name='VolumeSlider7') #Control Bank B - Channel 2 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- self._Encoder8 = EncoderElement(MIDI_CC_TYPE,2,22, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder8') self._Encoder9 = EncoderElement(MIDI_CC_TYPE,2,23, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder9') self._Encoder10 = EncoderElement(MIDI_CC_TYPE,2,24, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder10') self._Encoder11 = EncoderElement(MIDI_CC_TYPE,2,25, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder11') self._Encoder12 = EncoderElement(MIDI_CC_TYPE,2,26, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder12') self._Encoder13 = EncoderElement(MIDI_CC_TYPE,2,27, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder13') self._Encoder14 = EncoderElement(MIDI_CC_TYPE,2,28, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder14') self._Encoder15 = EncoderElement(MIDI_CC_TYPE,2,29, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder15') self._ArmButton8 = ButtonElement(False, MIDI_CC_TYPE, 1, 32, name='ArmButton8') self._ArmButton9 = ButtonElement(False, MIDI_CC_TYPE, 1, 33, name='ArmButton9') self._ArmButton10 = ButtonElement(False, MIDI_CC_TYPE, 1, 34, name='ArmButton10') self._ArmButton11 = ButtonElement(False, MIDI_CC_TYPE, 1, 35, name='ArmButton11') self._ArmButton12 = ButtonElement(False, MIDI_CC_TYPE, 1, 36, name='ArmButton12') self._ArmButton13 = ButtonElement(False, MIDI_CC_TYPE, 1, 37, name='ArmButton13') self._ArmButton14 = ButtonElement(False, MIDI_CC_TYPE, 1, 38, name='ArmButton14') self._ArmButton15 = ButtonElement(False, MIDI_CC_TYPE, 1, 39, name='ArmButton15') self._VolumeSlider8 = SliderElement(MIDI_CC_TYPE, 1, 12, name='VolumeSlider8') self._VolumeSlider9 = SliderElement(MIDI_CC_TYPE, 1, 13, name='VolumeSlider9') self._VolumeSlider10 = SliderElement(MIDI_CC_TYPE, 1, 14, name='VolumeSlider10') self._VolumeSlider11 = SliderElement(MIDI_CC_TYPE, 1, 15, name='VolumeSlider11') self._VolumeSlider12 = SliderElement(MIDI_CC_TYPE, 1, 16, name='VolumeSlider12') self._VolumeSlider13 = SliderElement(MIDI_CC_TYPE, 1, 17, name='VolumeSlider13') self._VolumeSlider14 = SliderElement(MIDI_CC_TYPE, 1, 18, name='VolumeSlider14') self._VolumeSlider15 = SliderElement(MIDI_CC_TYPE, 1, 19, name='VolumeSlider15') #Control Bank C - Channel 3 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- self._Encoder16 = EncoderElement(MIDI_CC_TYPE,3,22, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder16') self._Encoder17 = EncoderElement(MIDI_CC_TYPE,3,23, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder17') self._Encoder18 = EncoderElement(MIDI_CC_TYPE,3,24, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder18') self._Encoder19 = EncoderElement(MIDI_CC_TYPE,3,25, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder19') self._Encoder20 = EncoderElement(MIDI_CC_TYPE,3,26, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder20') self._Encoder21 = EncoderElement(MIDI_CC_TYPE,3,27, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder21') self._Encoder22 = EncoderElement(MIDI_CC_TYPE,3,28, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder22') self._Encoder23 = EncoderElement(MIDI_CC_TYPE,3,29, Live.MidiMap.MapMode.relative_two_compliment, name='Encoder23') self._ArmButton16 = ButtonElement(False, MIDI_CC_TYPE, 2, 32, name='ArmButton16') self._ArmButton17 = ButtonElement(False, MIDI_CC_TYPE, 2, 33, name='ArmButton17') self._ArmButton18 = ButtonElement(False, MIDI_CC_TYPE, 2, 34, name='ArmButton18') self._ArmButton19 = ButtonElement(False, MIDI_CC_TYPE, 2, 35, name='ArmButton19') self._ArmButton20 = ButtonElement(False, MIDI_CC_TYPE, 2, 36, name='ArmButton20') self._ArmButton21 = ButtonElement(False, MIDI_CC_TYPE, 2, 37, name='ArmButton21') self._ArmButton22 = ButtonElement(False, MIDI_CC_TYPE, 2, 38, name='ArmButton22') self._ArmButton23 = ButtonElement(False, MIDI_CC_TYPE, 2, 39, name='ArmButton23') self._VolumeSlider16 = SliderElement(MIDI_CC_TYPE, 2, 12, name='VolumeSlider16') self._VolumeSlider17 = SliderElement(MIDI_CC_TYPE, 2, 13, name='VolumeSlider17') self._VolumeSlider18 = SliderElement(MIDI_CC_TYPE, 2, 14, name='VolumeSlider18') self._VolumeSlider19 = SliderElement(MIDI_CC_TYPE, 2, 15, name='VolumeSlider19') self._VolumeSlider20 = SliderElement(MIDI_CC_TYPE, 2, 16, name='VolumeSlider20') self._VolumeSlider21 = SliderElement(MIDI_CC_TYPE, 2, 17, name='VolumeSlider21') self._VolumeSlider22 = SliderElement(MIDI_CC_TYPE, 2, 18, name='VolumeSlider22') self._VolumeSlider23 = SliderElement(MIDI_CC_TYPE, 2, 19, name='VolumeSlider23') #Drum Bank A - Channel 4-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- self._Pad0 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 81, name='Pad0') self._Pad1 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 83, name='Pad1') self._Pad2 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 84, name='Pad2') self._Pad3 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 86, name='Pad3') self._Pad4 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 74, name='Pad4') self._Pad5 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 76, name='Pad5') self._Pad6 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 77, name='Pad6') self._Pad7 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 79, name='Pad7') self._Pad8 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 67, name='Pad8') self._Pad9 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 69, name='Pad9') self._Pad10 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 71, name='Pad10') self._Pad11 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 72, name='Pad11') self._Pad12 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 60, name='Pad12') self._Pad13 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 62, name='Pad13') self._Pad14 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 64, name='Pad14') self._Pad15 = ButtonElement(True, MIDI_NOTE_TYPE, 3, 65, name='Pad15') self._Pads = ButtonMatrixElement(rows=[[self._Pad0, self._Pad1, self._Pad2, self._Pad3], [self._Pad4, self._Pad5, self._Pad6, self._Pad7], [self._Pad8, self._Pad9, self._Pad10, self._Pad11], [self._Pad12, self._Pad13, self._Pad14, self._Pad15]]) #Drum Bank B ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #Drum Bank C ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #Drum Bank D ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # #Drum rack ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- drum_rack = DrumRackComponent(name='Drum_Rack', is_enabled=False, layer=Layer(pads=self._Pads)) drum_rack.set_enabled(True) #Transport ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer(play_button=midimap['Play'], record_button=midimap['Record'], stop_button=midimap['Stop'], loop_button=midimap['Loop'])) #, seek_forward_button=midimap['Forward'], seek_backward_button=midimap['Backward'] transport.set_enabled(True) #Make the Back/Fwd button just normal mapable CC senders self._BackButton = ButtonElement(False, MIDI_CC_TYPE, 0, 116, name='BackButton') self._FwdButton = ButtonElement(False, MIDI_CC_TYPE, 0, 115, name='FwdButton') #Device ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- self._device = DeviceComponent(name='Device', is_enabled=False, layer=Layer(parameter_controls=midimap['Encoders']), device_selection_follows_track_selection=True) self._device.set_enabled(True) self.set_device_component(self._device) #Mixer ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- mixer_size = 24 self._mixer = MixerComponent(mixer_size, name='Mixer', is_enabled=False) #Super crude and repetitive mapping because after all this shit I'm not spending time learning how to loop this crap hehe #Bank A self._mixer.channel_strip(0).layer = Layer(volume_control = self._VolumeSlider0, arm_button=self._ArmButton0, pan_control=self._Encoder0) self._mixer.channel_strip(1).layer = Layer(volume_control = self._VolumeSlider1, arm_button=self._ArmButton1, pan_control=self._Encoder1) self._mixer.channel_strip(2).layer = Layer(volume_control = self._VolumeSlider2, arm_button=self._ArmButton2, pan_control=self._Encoder2) self._mixer.channel_strip(3).layer = Layer(volume_control = self._VolumeSlider3, arm_button=self._ArmButton3, pan_control=self._Encoder3) self._mixer.channel_strip(4).layer = Layer(volume_control = self._VolumeSlider4, arm_button=self._ArmButton4, pan_control=self._Encoder4) self._mixer.channel_strip(5).layer = Layer(volume_control = self._VolumeSlider5, arm_button=self._ArmButton5, pan_control=self._Encoder5) self._mixer.channel_strip(6).layer = Layer(volume_control = self._VolumeSlider6, arm_button=self._ArmButton6, pan_control=self._Encoder6) self._mixer.channel_strip(7).layer = Layer(volume_control = self._VolumeSlider7, arm_button=self._ArmButton7, pan_control=self._Encoder7) #Bank B self._mixer.channel_strip(8).layer = Layer(volume_control = self._VolumeSlider8, arm_button=self._ArmButton8, pan_control=self._Encoder8) self._mixer.channel_strip(9).layer = Layer(volume_control = self._VolumeSlider9, arm_button=self._ArmButton9, pan_control=self._Encoder9) self._mixer.channel_strip(10).layer = Layer(volume_control = self._VolumeSlider10, arm_button=self._ArmButton10, pan_control=self._Encoder10) self._mixer.channel_strip(11).layer = Layer(volume_control = self._VolumeSlider11, arm_button=self._ArmButton11, pan_control=self._Encoder11) self._mixer.channel_strip(12).layer = Layer(volume_control = self._VolumeSlider12, arm_button=self._ArmButton12, pan_control=self._Encoder12) self._mixer.channel_strip(13).layer = Layer(volume_control = self._VolumeSlider13, arm_button=self._ArmButton13, pan_control=self._Encoder13) self._mixer.channel_strip(14).layer = Layer(volume_control = self._VolumeSlider14, arm_button=self._ArmButton14, pan_control=self._Encoder14) self._mixer.channel_strip(15).layer = Layer(volume_control = self._VolumeSlider15, arm_button=self._ArmButton15, pan_control=self._Encoder15) #Bank C self._mixer.channel_strip(16).layer = Layer(volume_control = self._VolumeSlider16, arm_button=self._ArmButton16, pan_control=self._Encoder16) self._mixer.channel_strip(17).layer = Layer(volume_control = self._VolumeSlider17, arm_button=self._ArmButton17, pan_control=self._Encoder17) self._mixer.channel_strip(18).layer = Layer(volume_control = self._VolumeSlider18, arm_button=self._ArmButton18, pan_control=self._Encoder18) self._mixer.channel_strip(19).layer = Layer(volume_control = self._VolumeSlider19, arm_button=self._ArmButton19, pan_control=self._Encoder19) self._mixer.channel_strip(20).layer = Layer(volume_control = self._VolumeSlider20, arm_button=self._ArmButton20, pan_control=self._Encoder20) self._mixer.channel_strip(21).layer = Layer(volume_control = self._VolumeSlider21, arm_button=self._ArmButton21, pan_control=self._Encoder21) self._mixer.channel_strip(22).layer = Layer(volume_control = self._VolumeSlider22, arm_button=self._ArmButton22, pan_control=self._Encoder22) self._mixer.channel_strip(23).layer = Layer(volume_control = self._VolumeSlider23, arm_button=self._ArmButton23, pan_control=self._Encoder23) self._mixer.set_enabled(True) #Track change listener self.song().view.add_selected_track_listener(self._update_selected_device)
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=b'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=b'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=b'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 BUTTON_HARDWARE_AND_MESSAGE_IDS.keys(): setattr(self, b'_' + button_name, make_keylab_button(button_name)) self._pads = ButtonMatrixElement(rows=[[ ButtonElement(True, MIDI_CC_TYPE, PAD_CHANNEL, col_index + row_offset, name=b'Pad_%d_%d' % (col_index, row_index)) for col_index in xrange(4) ] for row_index, row_offset in enumerate(xrange(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, b' ') + b'\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(b'KeyLab') self._display_line2_data_source.set_display_string(b'Ableton Live') def _create_device(self): self._device = DeviceComponent( name=b'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=b'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=b'Drums', is_enabled=False, layer=Layer(pads=self._pads)) self._drums.set_enabled(True) def _create_transport(self): self._transport = TransportComponent( name=b'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=b'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=b'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=b'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 izip(ENCODER_HARDWARE_IDS, ENCODER_MSG_IDS): self._setup_hardware_encoder(hardware_id, identifier, ENCODER_CHANNEL) for hardware_id, identifier in izip(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.itervalues( ): self._setup_hardware_button(hardware_id, identifier) for hardware_id, identifier in izip(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)
class OhmModes(ControlSurface): __module__ = __name__ __doc__ = " OhmModes controller script " def __init__(self, c_instance): """everything except the '_on_selected_track_changed' override and 'disconnect' runs from here""" ControlSurface.__init__(self, c_instance) self.set_suppress_rebuild_requests(True) # Turn off rebuild MIDI map until after we're done setting up """MonoComponent specific variables - best not change these unless you know what you're doing""" self._version_check = 'b994' self._host_name = 'Ohm' self._color_type = 'OhmRGB' self._hosts = [] self.hosts = [] self._client = [None for index in range(6)] self._active_client = None self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< OhmModes ' + str(self._version_check) + ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>') self._rgb = 0 self._timer = 0 self._touched = 0 self.flash_status = 1 self._backlight = 127 self._backlight_type = 'static' self._ohm = 127 self._ohm_type = 'static' self._pad_translations = PAD_TRANSLATION self._device_selection_follows_track_selection = FOLLOW self._keys_octave = 5 self._keys_scale = 0 self._tempo_buttons = None self._setup_monobridge() self._setup_controls() self._setup_transport_control() # Run the transport setup part of the script self._setup_mixer_control() # Setup the mixer object self._setup_session_control() # Setup the session object self._setup_device_control() # Setup the device object self._setup_crossfader() self._setup_ohmmod() self._setup_switchboard() self._setup_modes() self._assign_page_constants() self._last_device = None self.set_suppress_rebuild_requests(False) #Turn rebuild back on, now that we're done setting up self.song().view.add_selected_track_listener(self._update_selected_device) self.show_message('OhmModes Control Surface Loaded') self._send_midi(tuple(switchxfader)) if FORCE_TYPE is True: self._rgb = FORCE_COLOR_TYPE else: self.schedule_message(10, self.query_ohm, None) def query_ohm(self): #self.log_message('querying Ohm') self._send_midi(tuple(check_model)) def update_display(self): """ Live -> Script Aka on_timer. Called every 100 ms and should be used to update display relevant parts of the controller """ for message in self._scheduled_messages: message['Delay'] -= 1 if (message['Delay'] == 0): if (message['Parameter'] != None): message['Message'](message['Parameter']) else: message['Message']() del self._scheduled_messages[self._scheduled_messages.index(message)] for callback in self._timer_callbacks: callback() self._timer = (self._timer + 1) % 256 self.flash() self.strobe() def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def get_device_bank(self): return self._device._bank_index def _setup_controls(self): is_momentary = True self._fader = [None for index in range(8)] self._dial = [None for index in range(16)] self._button = [None for index in range(8)] self._menu = [None for index in range(6)] for index in range(8): self._fader[index] = MonoEncoderElement2(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self) #self._fader[index].name = 'Fader_' + str(index), self for index in range(8): self._button[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self) for index in range(16): self._dial[index] = CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), index, self) #self._dial[index].name = 'Dial_' + str(index) self._knobs = [] for index in range(12): self._knobs.append(self._dial[index]) for index in range(6): self._menu[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self) self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute) self._crossfader.name = "Crossfader" self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self) self._shift_l = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Page_Button_Left', self) self._shift_r = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Page_Button_Right', self) self._matrix = ButtonMatrixElement() self._matrix.name = 'Matrix' self._grid = [None for index in range(8)] self._monomod = ButtonMatrixElement() self._monomod.name = 'Monomod' for column in range(8): self._grid[column] = [None for index in range(8)] for row in range(8): self._grid[column][row] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (column * 8) + row, 'Grid_' + str(column) + '_' + str(row), self) for row in range(5): button_row = [] for column in range(7): button_row.append(self._grid[column][row]) self._matrix.add_row(tuple(button_row)) for row in range(8): button_row = [] for column in range(8): button_row.append(self._grid[column][row]) self._monomod.add_row(tuple(button_row)) """We'll also need to assign some of our controls to ButtonMatrixElements so that we can use them with the Session Zoom and the Mod components""" """We use the same formula here: first we create the holders:""" self._mod_matrix = ButtonMatrixElement() #this is a standard _Framework object used by many of the other scripts self._mod_matrix.name = 'Matrix' self._dial_matrix = EncoderMatrixElement(self) #this is a special Mono object, used specifically for the mod components self._dial_matrix.name = 'Dial_Matrix' self._dial_button_matrix = ButtonMatrixElement() #this is a special Mono object, used specifically for the mod components self._dial_button_matrix.name = 'Dial_Button_Matrix' """And then we fill the with the control elements that are assigned to them""" for row in range(4): #we have 4 rows, and 4 columns, forming the 4x4 grid in the center of the controller button_row = [] #since the matrix is two dimensional, first we create the outer array, for column in range(4): button_row.append(self._grid[column+4][row]) #then we create the inner array. The process is the same for the other controls here. self._mod_matrix.add_row(tuple(button_row)) #add_row() is a method of the ButtonMatrixElement. You can look in its parent module to see how it works for row in range(3): dial_row = [] for column in range(4): dial_row.append(self._dial[(row*4) + column]) self._dial_matrix.add_row(tuple(dial_row)) for row in range(3): dial_button_row = [] for column in range(4): dial_button_row.append(self._grid[column][row]) self._dial_button_matrix.add_row(tuple(dial_button_row)) self._key = [self._grid[KEYS[index][1]][KEYS[index][0]] for index in range(32)] self._encoder = [self._dial[index] for index in range(12)] self._key_matrix = ButtonMatrixElement() button_row = [] #since we only use one row for the chopper, we can define a 1 dimensional button matrix for this one. for column in range(16): #We use the ButtonMatrixObject because it takes care of setting up callbacks for all the buttons easily when we need them later button_row.append(self._key[16 + column]) self._key_matrix.add_row(tuple(button_row)) def _setup_ohmmod(self): self._host = MonomodComponent(self) self._host.name = 'Monomod_Host' self.hosts = [self._host] self._hosts = [self._host] for index in range(6): self._client[index] = MonoClient(self, index) self._client[index].name = 'Client_' + str(index) #self._client[index]._mod_dial = self._encoder[index] self._client[index]._device_component.set_parameter_controls(tuple([self._dial[num] for num in range(12)])) #assign the encoders to the clients so that we can control device parameters through our client self._client[index]._control_defs = {'dials':self._dial_matrix, 'buttons':self._dial_button_matrix, 'grid':self._mod_matrix, 'keys':self._key, 'knobs':[self._dial[num+12] for num in range(4)]} #assign controls that raw data will be addressed at self._host._active_client = self._client[0] self._host._active_client._is_active = True self._host.connect_to_clients(self) def _setup_switchboard(self): self._switchboard = SwitchboardElement(self, self._client) self._switchboard.name = 'Switchboard' def _setup_modes(self): self._shift_mode = ShiftModeComponent(self) self._shift_mode.name = 'Shift_Mode' self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r, self._livid) self._scale_mode = ScaleModeComponent(self) self._scale_mode.name = "Scale_Mode" self._octave_mode = OctaveModeComponent(self) self._octave_mode.name = "Octave_Mode" self._modNum = ModNumModeComponent(self, self.modNum_update) self._modNum.name = 'Mod_Number' self._modNum.set_mode = self._modNum_set_mode(self._modNum) self._modNum.set_mode_buttons([self._menu[index] for index in range(6)]) def _modNum_set_mode(self, modNum): def set_mode(mode): if modNum._is_enabled == True: assert isinstance(mode, int) assert (mode in range(modNum.number_of_modes())) if (modNum._mode_index != mode): modNum._mode_index = mode modNum.update() return set_mode def _setup_transport_control(self): self._transport = TransportComponent() self._transport.name = 'Transport' def _setup_mixer_control(self): is_momentary = True self._num_tracks = (7) #A mixer is one-dimensional; global mixer mixer = SpecialMixerComponent(7, 0, True, False) mixer.name = 'Mixer' self._mixer = mixer mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left) for index in range(7): mixer.channel_strip(index).set_volume_control(self._fader[index]) for index in range(7): mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index) mixer.track_eq(index).name = 'Mixer_EQ_' + str(index) mixer.channel_strip(index)._invert_mute_feedback = True self.song().view.selected_track = mixer.channel_strip(0)._track #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error def _setup_session_control(self): is_momentary = True num_tracks = 7 num_scenes = 5 global session session = SessionComponent(num_tracks, num_scenes) session.name = "Session" self._session = session session.set_offsets(0, 0) self._scene = [None for index in range(6)] for row in range(num_scenes): self._scene[row] = session.scene(row) self._scene[row].name = 'Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_' + str(row) session.set_mixer(self._mixer) self._session_zoom = SessionZoomingComponent(session) self._session_zoom.name = 'Session_Overview' def _assign_session_colors(self): self.log_message('assign session colors') num_tracks = 7 num_scenes = 5 self._session.set_stop_track_clip_value(STOP_CLIP_COLOR[self._rgb]) for row in range(num_scenes): for column in range(num_tracks): self._scene[row].clip_slot(column).set_triggered_to_play_value(CLIP_TRIGD_TO_PLAY_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_triggered_to_record_value(CLIP_TRIGD_TO_RECORD_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_stopped_value(CLIP_STOPPED_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_recording_value(CLIP_RECORDING_COLOR[self._rgb]) self._session_zoom.set_stopped_value(ZOOM_STOPPED_COLOR[self._rgb]) self._session_zoom.set_playing_value(ZOOM_PLAYING_COLOR[self._rgb]) self._session_zoom.set_selected_value(ZOOM_SELECTED_COLOR[self._rgb]) for row in range(8): for column in range(8): self._grid[column][row].set_force_next_value() self._session.on_scene_list_changed() self._shift_mode.update() def _setup_device_control(self): self._device = DeviceComponent() self._device.name = 'Device_Component' self.set_device_component(self._device) self._device_navigator = DetailViewControllerComponent() self._device_navigator.name = 'Device_Navigator' self._device_selection_follows_track_selection = FOLLOW def device_follows_track(self, val): self._device_selection_follows_track_selection = (val == 1) return self def _setup_crossfader(self): self._mixer.set_crossfader_control(self._crossfader) def disconnect(self): """clean things up on disconnect""" self.song().view.remove_selected_track_listener(self._update_selected_device) self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= OhmModes log closed =--------------") #Create entry in log file ControlSurface.disconnect(self) return None def _get_num_tracks(self): return self.num_tracks def flash(self): #if(self.flash_status > 0): for row in range(8): if(self._button[row]._flash_state > 0): self._button[row].flash(self._timer) for column in range(8): button = self._grid[column][row] if(button._flash_state > 0): button.flash(self._timer) 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 deassign_matrix(self): self._host._set_knobs(None) self._host._set_button_matrix(None) self._host.set_enabled(False) self._modNum.set_enabled(False) self.assign_alternate_mappings(0) self._scale_mode.set_mode_buttons(None) self._scale_mode.set_enabled(False) self._octave_mode.set_mode_buttons(None) self._octave_mode.set_enabled(False) #self._session_zoom.set_button_matrix(None) self._session_zoom.set_enabled(False) self._session_zoom.set_nav_buttons(None, None, None, None) self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) self._transport.set_enabled(False) for column in range(4): #self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]])) self._mixer.track_eq(column)._gain_controls = None self._mixer.track_eq(column).set_enabled(False) for column in range(7): self._mixer.channel_strip(column).set_crossfade_toggle(None) self._mixer.channel_strip(column).set_mute_button(None) self._mixer.channel_strip(column).set_solo_button(None) self._mixer.channel_strip(column).set_arm_button(None) self._mixer.channel_strip(column).set_send_controls(None) self._mixer.channel_strip(column).set_pan_control(None) self._mixer.track_eq(column).set_enabled(False) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(None) for column in range(8): self._button[column]._on_value = SELECT_COLOR[self._rgb] for row in range(8): self._grid[column][row].set_channel(0) self._grid[column][row].release_parameter() self._grid[column][row].use_default_message() self._grid[column][row].set_enabled(True) self._grid[column][row].send_value(0, True) self._grid[column][row]._on_value = 127 self._grid[column][row]._off_value = 0 for index in range(6): self._menu[index]._on_value = 127 self._menu[index]._off_value = 0 for index in range(16): self._dial[index].use_default_message() self._dial[index].release_parameter() #self._dial[index].set_enabled(True) if(self._device._parameter_controls != None): for control in self._device._parameter_controls: control.release_parameter() self._device._parameter_controls = None self._device.set_enabled(False) self._device_navigator.set_enabled(False) self._mixer.update() self._matrix.reset() #self._transport.set_play_button(None) #self._transport.set_stop_button(None) self.request_rebuild_midi_map() def _assign_page_constants(self): #self._session_zoom.set_zoom_button(self._button[7]) #commented out pn 070111 self._session_zoom.set_zoom_button(self._grid[7][7]) #added pn 070111 self._session_zoom.set_button_matrix(self._matrix) #self._session_zoom.set_enabled(True) for column in range(7): self._mixer.channel_strip(column).set_select_button(self._button[column]) self._mixer.channel_strip(column).set_volume_control(self._fader[column]) self._mixer.master_strip().set_volume_control(self._fader[7]) self._mixer.master_strip().set_select_button(self._button[7]) #added pn 070111 self._mixer.set_prehear_volume_control(self._dial[15]) self._transport.set_play_button(self._menu[0]) self._menu[0].send_value(PLAY_COLOR[self._rgb], True) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._transport.set_stop_button(self._menu[1]) self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._menu[1].send_value(STOP_COLOR[self._rgb], True) #self._livid._on_value = TAP_COLOR[self._rgb] #self._transport.set_tap_tempo_button(self._livid) #self._livid.send_value(TAP_COLOR, True) self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[4]) def assign_page_0(self): self._backlight_type = 'static' #self._session_zoom.set_button_matrix(self._matrix) self._session_zoom.set_enabled(True) for column in range(7): self._grid[column][5]._on_value = MUTE_COLOR[self._rgb] self._mixer.channel_strip(column).set_mute_button(self._grid[column][5]) self._grid[column][6]._on_value = SOLO_COLOR[self._rgb] self._mixer.channel_strip(column).set_solo_button(self._grid[column][6]) self._grid[column][7]._on_value = ARM_COLOR[self._rgb] self._mixer.channel_strip(column).set_arm_button(self._grid[column][7]) self._mixer.channel_strip(column).set_pan_control(self._dial[column + 8]) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) for column in range(4): self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column], self._dial[column + 4]])) for index in range(5): self._grid[7][index]._off_value = SCENE_LAUNCH_COLOR[self._rgb] self._scene[index].set_launch_button(self._grid[7][index]) self._grid[7][index].set_force_next_value() self._grid[7][index].turn_off() for index in range(4): self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb] self._session.set_track_bank_buttons(self._menu[4], self._menu[3]) self._session.set_scene_bank_buttons(self._menu[5], self._menu[2]) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) def assign_page_1(self): self._backlight_type = 'pulse' self._session_zoom.set_enabled(False) for column in range(4): for row in range(4): self._grid[column][row].set_channel(PAGE1_DRUM_CHANNEL) self._grid[column][row].set_identifier(PAGE1_DRUM_MAP[column][row]) self._grid[column][row].send_value(DRUM_COLOR[self._rgb], True) self._grid[column][row].set_enabled(False) self._grid[column + 4][row].set_channel(PAGE1_BASS_CHANNEL) self._grid[column + 4][row].set_identifier(PAGE1_BASS_MAP[column][row]) self._grid[column + 4][row].send_value(BASS_COLOR[self._rgb], True) self._grid[column + 4][row].set_enabled(False) scale_mode_buttons = [] for column in range(8): for row in range(3): self._grid[column][row + 4].set_enabled(False) self._grid[column][row + 4].set_channel(PAGE1_KEYS_CHANNEL) self._grid[column][row + 4].set_identifier(int(PAGE1_KEYS_MAP[column][row]) + int(PAGE1_MODES_MAP[self._scale_mode._mode_index][column]) + int(self._octave_mode._mode_index * 12)) self._grid[column][row + 4].send_value(KEYS_COLOR[self._rgb], True) for row in range(1): scale_mode_buttons.append(self._grid[column][7]) self._scale_mode.set_mode_buttons(tuple(scale_mode_buttons)) self._scale_mode.set_enabled(True) self._octave_mode.set_mode_buttons(tuple([self._menu[5], self._menu[2]])) self._octave_mode.set_enabled(True) for column in range(7): self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column + 8]])) self._mixer.channel_strip(column).set_arm_button(self._button[column]) self._device.set_enabled(True) device_param_controls = [] for index in range(8): device_param_controls.append(self._dial[index]) self._device.set_parameter_controls(tuple(device_param_controls)) self._menu[0]._on_value = (PLAY_COLOR[self._rgb]) for index in range(4): self._menu[2 + index]._on_value = (DEVICE_NAV_COLOR[self._rgb]) self._device_navigator.set_enabled(True) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) def assign_page_2(self): self._backlight_type = 'up' #self._session_zoom.set_button_matrix(self._matrix) self._session_zoom.set_enabled(True) for column in range(7): self._grid[column][5]._on_value = MUTE_COLOR[self._rgb] self._mixer.channel_strip(column).set_mute_button(self._grid[column][5]) self._grid[column][6]._on_value = CROSSFADE_ASSIGN_COLOR[self._rgb] self._mixer.channel_strip(column).set_crossfade_toggle(self._grid[column][6]) self._grid[column][7].set_channel(2) self._grid[column][7].set_identifier(column) self._grid[column][7].reset() self._grid[column][7].set_enabled(False) self._grid[column][7].send_value(4, True) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) for row in range(5): self._grid[7][row]._off_value = SCENE_LAUNCH_COLOR[self._rgb] self._scene[row].set_launch_button(self._grid[7][row]) self._grid[7][row].set_force_next_value() self._grid[7][row].turn_off() for column in range(4): self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]])) self._mixer.track_eq(column).set_enabled(True) for column in range(3): self._mixer.channel_strip(column+4).set_pan_control(self._dial[column + 12]) for index in range(4): self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb] self._session.set_track_bank_buttons(self._menu[4], self._menu[3]) self._session.set_scene_bank_buttons(self._menu[5], self._menu[2]) self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]]) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) """ def assign_page_0(self): self._backlight_type = 'static' #self._session_zoom.set_button_matrix(self._matrix) self._transport.set_play_button(self._menu[0]) self._transport.set_stop_button(self._menu[1]) self._session_zoom.set_enabled(True) for column in range(7): self._grid[column][5]._on_value = MUTE_COLOR[self._rgb] self._mixer.channel_strip(column).set_mute_button(self._grid[column][5]) self._grid[column][6]._on_value = SOLO_COLOR[self._rgb] self._mixer.channel_strip(column).set_solo_button(self._grid[column][6]) self._grid[column][7]._on_value = ARM_COLOR[self._rgb] self._mixer.channel_strip(column).set_arm_button(self._grid[column][7]) self._mixer.channel_strip(column).set_pan_control(self._dial[column + 8]) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) for column in range(4): self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column], self._dial[column + 4]])) for index in range(5): self._grid[7][index]._off_value = SCENE_LAUNCH_COLOR[self._rgb] self._scene[index].set_launch_button(self._grid[7][index]) for index in range(4): self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb] self._session.set_track_bank_buttons(self._menu[4], self._menu[3]) self._session.set_scene_bank_buttons(self._menu[5], self._menu[2]) def assign_page_1(self): self._backlight_type = 'pulse' self._transport.set_play_button(self._menu[0]) self._transport.set_stop_button(self._menu[1]) self._session_zoom.set_enabled(False) for column in range(8): for row in range(8): self._grid[row][column].set_channel(JESSE_MAP_CHAN) self._grid[row][column].set_identifier(JESSE_MAP[column][row]) self._grid[row][column].send_value(JESSE_MAP_COLORS[self._rgb], True) self._grid[row][column].set_enabled(False) ""self._grid[column + 4][row].set_channel(PAGE1_BASS_CHANNEL) self._grid[column + 4][row].set_identifier(PAGE1_BASS_MAP[column][row]) self._grid[column + 4][row].send_value(BASS_COLOR[self._rgb], True) self._grid[column + 4][row].set_enabled(False) scale_mode_buttons = [] for column in range(8): for row in range(3): self._grid[column][row + 4].set_enabled(False) self._grid[column][row + 4].set_channel(PAGE1_KEYS_CHANNEL) self._grid[column][row + 4].set_identifier(int(PAGE1_KEYS_MAP[column][row]) + int(PAGE1_MODES_MAP[self._scale_mode._mode_index][column]) + int(self._octave_mode._mode_index * 12)) self._grid[column][row + 4].send_value(KEYS_COLOR[self._rgb], True) for row in range(1): scale_mode_buttons.append(self._grid[column][7])"" #self._scale_mode.set_mode_buttons(tuple(scale_mode_buttons)) #self._scale_mode.set_enabled(True) #self._octave_mode.set_mode_buttons(tuple([self._menu[5], self._menu[2]])) #self._octave_mode.set_enabled(True) for column in range(7): self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column + 8]])) self._mixer.channel_strip(column).set_arm_button(self._button[column]) self._device.set_enabled(True) device_param_controls = [] for index in range(8): device_param_controls.append(self._dial[index]) self._device.set_parameter_controls(tuple(device_param_controls)) for index in range(4): self._menu[2 + index]._on_value = (DEVICE_NAV_COLOR[self._rgb]) self._device_navigator.set_enabled(True) def assign_page_2(self): self._backlight_type = 'up' self._transport.set_play_button(self._menu[0]) self._transport.set_stop_button(self._menu[1]) #self._session_zoom.set_button_matrix(self._matrix) self._session_zoom.set_enabled(True) for column in range(7): self._grid[column][5]._on_value = MUTE_COLOR[self._rgb] self._mixer.channel_strip(column).set_mute_button(self._grid[column][5]) self._grid[column][6]._on_value = CROSSFADE_ASSIGN_COLOR[self._rgb] self._mixer.channel_strip(column).set_crossfade_toggle(self._grid[column][6]) self._grid[column][7].set_channel(2) self._grid[column][7].set_identifier(column) self._grid[column][7].reset() self._grid[column][7].set_enabled(False) self._grid[column][7].send_value(4, True) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) for row in range(5): self._grid[7][row]._off_value = SCENE_LAUNCH_COLOR[self._rgb] self._scene[row].set_launch_button(self._grid[7][row]) for column in range(4): self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]])) self._mixer.track_eq(column).set_enabled(True) for column in range(3): self._mixer.channel_strip(column+4).set_pan_control(self._dial[column + 12]) for index in range(4): self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb] self._session.set_track_bank_buttons(self._menu[4], self._menu[3]) self._session.set_scene_bank_buttons(self._menu[5], self._menu[2]) self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]]) """ def assign_mod(self): self.deassign_matrix() #self.set_local_ring_control(self._host._active_client._local_ring_control) self._host.set_enabled(True) self._modNum.set_enabled(True) self._host._set_dial_matrix(self._dial_matrix, self._dial_button_matrix) self._host._set_button_matrix(self._mod_matrix) self._host._set_key_buttons(tuple(self._key)) if not self._host._active_client.is_connected(): self.assign_alternate_mappings(self._modNum._mode_index + 1) def modNum_update(self): if self._modNum._is_enabled == True: self.assign_alternate_mappings(0) self._host._select_client(int(self._modNum._mode_index)) self._host.display_active_client() if not self._host._active_client.is_connected(): self.assign_alternate_mappings(self._modNum._mode_index + 1) for button in self._modNum._modes_buttons: if self._modNum._mode_index == self._modNum._modes_buttons.index(button): button.send_value(1) else: button.send_value(self._client[self._modNum._modes_buttons.index(button)]._mod_color) #button.send_value(int(self._modNum._mode_index == self._modNum._modes_buttons.index(button))*self._host._active_client._mod_color) def assign_alternate_mappings(self, chan): for column in range(8): for row in range(8): #self._grid[column][row].set_identifier(OHM_MAP_ID[column][row]) self._grid[column][row].set_channel(chan) #self._grid[column][row].send_value(OHM_MAP_VALUE[column][row]) self._grid[column][row].set_enabled(chan is 0) for knob in self._encoder: knob.set_channel(chan) knob.set_enabled(chan is 0) self.request_rebuild_midi_map() def display_mod_colors(self): #for index in range(6): #set up a recursion of 6 # self._modNum._modes_buttons[index].send_value(self._client[index]._mod_color) #update the modLEDs to display the color assigned to its contained mod pass def _update_selected_device(self): if self._device_selection_follows_track_selection is True: track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and 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.set_device(device_to_select) self.set_appointed_device(device_to_select) #self._device_selector.set_enabled(True) self.request_rebuild_midi_map() return None def handle_sysex(self, midi_bytes): #self.log_message(str('>>sysexIN') + str(midi_bytes)) if len(midi_bytes) > 10: #self.log_message(str('>>sysex>10') + str(midi_bytes[:11])) if midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 7]): self.log_message(str('>>>color detected')) self._rgb = 0 elif midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 2]): self.log_message(str('>>>mono detected')) self._rgb = 1 self._assign_session_colors() """this method can be linked to from m4l, and provides a way to update the parameter value of an assigned DeviceComponent parameter control""" def to_encoder(self, num, val): rv=int(val*127) self._device._parameter_controls[num].receive_value(rv) p = self._device._parameter_controls[num]._parameter_to_map_to newval = (val * (p.max - p.min)) + p.min p.value = newval """this method sets the instance variable for local ring control, and sends the appropriate sysex string to change states on the CNTRLR""" def set_local_ring_control(self, val = 1): self._local_ring_control = (val!=0) """if(self._local_ring_control is True): self._send_midi(tuple([240, 0, 1, 97, 8, 32, 0, 247])) else: self._send_midi(tuple([240, 0, 1, 97, 8, 32, 1, 247]))""" """this method sets the instance variable for absolute encoder changes, and sends the appropriate sysex string to change states on the CNTRLR""" def set_absolute_mode(self, val = 1): self._absolute_mode = (val!=0) """if self._absolute_mode is True: self._send_midi(tuple([240, 0, 1, 97, 8, 17, 0, 0, 0, 0, 0, 0, 0, 0, 247])) else: self._send_midi(tuple([240, 0, 1, 97, 8, 17, 127, 127, 127, 127, 127, 127, 127, 127, 247]))""" """this method is used to update the individual elements of the encoder rings when the CNTRLR is in local ring control mode""" def send_ring_leds(self): """if self._host._is_enabled == True: leds = [240, 0, 1, 97, 8, 31] for index in range(12): wheel = self._encoder[index] bytes = wheel._get_ring() leds.append(bytes[0]) leds.append(int(bytes[1]) + int(bytes[2])) leds.append(247) self._send_midi(tuple(leds))""" pass def receive_midi(self, midi_bytes): """ Live -> Script MIDI messages are only received through this function, when explicitly forwarded in 'build_midi_map'. """ assert (midi_bytes != None) assert isinstance(midi_bytes, tuple) ##self.log_message('got message' + str(midi_bytes)) self.set_suppress_rebuild_requests(True) if (len(midi_bytes) is 3): msg_type = (midi_bytes[0] & 240) forwarding_key = [midi_bytes[0]] if (msg_type is not MIDI_PB_TYPE): forwarding_key.append(midi_bytes[1]) if (tuple(forwarding_key) in self._forwarding_registry.keys()): recipient = self._forwarding_registry[tuple(forwarding_key)] if (recipient != None): recipient.receive_value(midi_bytes[2]) else: self.log_message(('Got unknown message: ' + str(midi_bytes))) else: self.handle_sysex(midi_bytes) self.set_suppress_rebuild_requests(False) def _set_tempo_buttons(self, buttons): if self._tempo_buttons != None: self._tempo_buttons[0].remove_value_listener(self._tempo_value) self._tempo_buttons[1].remove_value_listener(self._tempo_value) self._tempo_buttons = buttons if buttons != None: for button in buttons: assert isinstance(button, FlashingButtonElement) self._tempo_buttons[0].set_on_off_values(4, 0) self._tempo_buttons[0].add_value_listener(self._tempo_value, True) self._tempo_buttons[1].set_on_off_values(4, 0) self._tempo_buttons[1].add_value_listener(self._tempo_value, True) self._tempo_buttons[0].turn_on() self._tempo_buttons[1].turn_on() def _tempo_value(self, value, sender): if (value > 0) and (self._tempo_buttons.index(sender) == 0): self.song().tempo = round(min((self.song().tempo + 1), 999)) elif (value > 0) and (self._tempo_buttons.index(sender) == 1): self.song().tempo = round(max((self.song().tempo - 1), 20)) """m4l bridge""" def generate_strip_string(self, display_string): #self.log_message(display_string) NUM_CHARS_PER_DISPLAY_STRIP = 12 if (not display_string): return (' ' * NUM_CHARS_PER_DISPLAY_STRIP) if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.endswith('dB') and (display_string.find('.') != -1))): display_string = display_string[:-2] if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)): for um in [' ', 'i', 'o', 'u', 'e', 'a']: while ((len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1)): um_pos = display_string.rfind(um, 1) display_string = (display_string[:um_pos] + display_string[(um_pos + 1):]) else: display_string = display_string.center((NUM_CHARS_PER_DISPLAY_STRIP - 1)) ret = u'' for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)): if ((ord(display_string[i]) > 127) or (ord(display_string[i]) < 0)): ret += ' ' else: ret += display_string[i] ret += ' ' #assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP) return ret def notification_to_bridge(self, name, value, sender): if(isinstance(sender, tuple([MonoEncoderElement2, CodecEncoderElement]))): self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name))) self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value))) 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) def get_clip_names(self): clip_names = [] for scene in self._session._scenes: for clip_slot in scene._clip_slots: if clip_slot.has_clip() is True: clip_names.append(clip_slot._clip_slot)##.clip.name) return clip_slot._clip_slot ##self.log_message(str(clip_slot._clip_slot.clip.name)) return clip_names def shift_update(self): pass