def _setup_device(self): self._encoders = [] for offset in range(8): self._encoders.append( PeekableEncoderElement( MIDI_CC_TYPE, 15, 17 + offset, Live.MidiMap.MapMode.relative_smooth_two_compliment)) self._encoders[(-1)].set_feedback_delay(-1) self._encoders[(-1)].add_value_listener((self._encoder_value), identify_sender=True) self._encoders[(-1)].name = 'Device_Control_' + str(offset) prev_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 14) next_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 15) prev_bank_button.name = 'Device_Bank_Down_Button' next_bank_button.name = 'Device_Bank_Up_Button' device = BestBankDeviceComponent( device_selection_follows_track_selection=True) device.name = 'Device_Component' self.set_device_component(device) device.set_parameter_controls(tuple(self._encoders)) device.set_bank_nav_buttons(prev_bank_button, next_bank_button) self._device_bank_buttons = (prev_bank_button, next_bank_button) prev_bank_button.add_value_listener(self._device_bank_value) next_bank_button.add_value_listener(self._device_bank_value) self._inst_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 109) self._inst_button.name = 'Inst_Button' self._inst_button.add_value_listener(self._inst_value) self._device_navigation = DetailViewCntrlComponent() self._device_navigation.name = 'Device_Navigation_Component'
def set_touch_mode(self, touchchannel): self.touch_mode = True nr_dev_ctrl = len(self._parameter_controls) for ctrl in self._parameter_controls: touch_button = ButtonElement(False, MIDI_CC_TYPE, touchchannel, ctrl.message_identifier()) self.del_touch_buttons.append(touch_button) touch_button.add_value_listener(self._clear_param, True)
class LaunchMod(Launchpad): def __init__(self, *a, **k): ControlSurface.__init__(self, *a, **k) with self.component_guard(): self._monomod_version = 'b996' self._host_name = 'LaunchMod' self._color_type = 'Launchpad' self._timer = 0 self._suppress_send_midi = True self._suppress_session_highlight = True self._suppress_highlight = False is_momentary = True self._suggested_input_port = 'Launchpad' self._suggested_output_port = 'Launchpad' self._control_is_with_automap = False self._user_byte_write_button = ButtonElement( is_momentary, MIDI_CC_TYPE, 0, 16) self._user_byte_write_button.name = 'User_Byte_Button' self._user_byte_write_button.send_value(1) self._user_byte_write_button.add_value_listener( self._user_byte_value) self._wrote_user_byte = False self._challenge = Live.Application.get_random_int( 0, 400000000) & 2139062143 matrix = ButtonMatrixElement() matrix.name = 'Button_Matrix' for row in range(8): button_row = [ ConfigurableButtonElement( is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column, str(column) + '_Clip_' + str(row) + '_Button', self) for column in range(8) ] matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0, optimized_send_midi=False) self._config_button.add_value_listener(self._config_value) top_button_names = [ 'Bank_Select_Up_Button', 'Bank_Select_Down_Button', 'Bank_Select_Left_Button', 'Bank_Select_Right_Button', 'Session_Button', 'User1_Button', 'User2_Button', 'Mixer_Button' ] side_button_names = [ 'Vol_Button', 'Pan_Button', 'SndA_Button', 'SndB_Button', 'Stop_Button', 'Trk_On_Button', 'Solo_Button', 'Arm_Button' ] top_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index, top_button_names[index], self) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], side_button_names[index], self) for index in range(8) ] self._side_buttons = ButtonMatrixElement() self._side_buttons.add_row(side_buttons) self._setup_monobridge() self._setup_mod() self._selector = MainSelectorComponent(self, matrix, tuple(top_buttons), tuple(side_buttons), self._config_button) self._selector.name = 'Main_Modes' for control in self.controls: isinstance(control, MonoButtonElement) and control.add_value_listener( self._button_value) self.set_highlighting_session_component( self._selector.session_component()) self._suppress_session_highlight = False self.log_message('--------------= ' + str(self._monomod_version) + ' log opened =--------------') """Mono overrides and additions""" def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_mod(self): self.monomodular = get_monomodular(self) self.monomodular.name = 'monomodular_switcher' self.modhandler = LaunchModHandler(self) self.modhandler.name = 'ModHandler' #self.modhandler.layer = Layer( lock_button = self._note_mode_button, push_grid = self._matrix, shift_button = self._shift_button, alt_button = self._select_button, key_buttons = self._track_state_buttons) #self.modhandler.layer.priority = 4 #self.modhandler.nav_buttons_layer = AddLayerMode( self.modhandler, Layer(nav_up_button = self._nav_up_button, nav_down_button = self._nav_down_button, nav_left_button = self._nav_left_button, nav_right_button = self._nav_right_button) ) def update_display(self): ControlSurface.update_display(self) self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if self.modhandler.is_enabled(): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer) def disconnect(self): super(LaunchMod, self).disconnect() rebuild_sys()
class MaschineChannelStripComponent(ChannelStripComponent): def __init__(self): ChannelStripComponent.__init__(self) self.deleted = {} self.clear_mode = False self.touch_mode = False self.send_control = None self.clear_vol_button = None self.clear_pan_button = None self.clear_send_button = None def set_touch_mode(self, touchchannel): self.touch_mode = True id_vol = self._volume_control.message_identifier() id_pan = self._pan_control.message_identifier() id_send = None for send in self._send_controls: if send: id_send = send.message_identifier() self.clear_vol_button = ButtonElement(False, MIDI_CC_TYPE, touchchannel, id_vol) self.clear_vol_button.add_value_listener(self._do_clear_vol) self.clear_pan_button = ButtonElement(False, MIDI_CC_TYPE, touchchannel, id_pan) self.clear_pan_button.add_value_listener(self._do_clear_pan) self.clear_send_button = ButtonElement(False, MIDI_CC_TYPE, touchchannel, id_send) self.clear_send_button.add_value_listener(self._do_clear_send) for send in self._send_controls: if send: self.send_control = send def enter_clear(self): self.clear_mode = True self.deleted = {} if not self.touch_mode: self.set_enabled(False) self._volume_control.add_value_listener(self._do_clear_vol) self._pan_control.add_value_listener(self._do_clear_pan) for send in self._send_controls: if send: self.send_control = send send.add_value_listener(self._do_clear_send) def exit_clear(self): self.clear_mode = False if not self.touch_mode: self._volume_control.remove_value_listener(self._do_clear_vol) self._pan_control.remove_value_listener(self._do_clear_pan) for send in self._send_controls: if send: send.remove_value_listener(self._do_clear_send) self.set_enabled(True) def _do_clear_vol(self, value): key = self._volume_control.message_identifier() if self.clear_mode: if key not in self.deleted: self.deleted[key] = True playing_clip = self._get_playing_clip() if playing_clip: playing_clip.clear_envelope(self._track.mixer_device.volume) def _do_clear_pan(self, value): key = self._pan_control.message_identifier() if self.clear_mode: if key not in self.deleted: self.deleted[key] = True playing_clip = self._get_playing_clip() if playing_clip: playing_clip.clear_envelope(self._track.mixer_device.panning) def _do_clear_send(self, value): key = self.send_control.message_identifier() if self.clear_mode: if key not in self.deleted: send_index = len(self._send_controls) - 1 self.deleted[key] = True playing_clip = self._get_playing_clip() if playing_clip: if send_index in range(len(self._track.mixer_device.sends)): playing_clip.clear_envelope(self._track.mixer_device.sends[send_index]) def _mute_value(self, value): super()._mute_value(value) key = self._mute_button.message_identifier() if self.clear_mode: if key not in self.deleted: self.deleted[key] = True playing_clip = self._get_playing_clip() if playing_clip: playing_clip.clear_envelope(self._track.mixer_device.track_activator) def _get_playing_clip(self): if self._track is None: return clips_slots = self._track.clip_slots for cs in clips_slots: if cs.has_clip and cs.is_playing: return cs.clip return def disconnect(self): self.clear_pan_button = None self.clear_send_button = None if self.clear_vol_button is not None: self.clear_vol_button.remove_value_listener(self._do_clear_vol) self.clear_vol_button = None elif self.clear_pan_button is not None: self.clear_pan_button.remove_value_listener(self._do_clear_pan) self.clear_pan_button = None else: if self.clear_send_button is not None: self.clear_send_button.remove_value_listener(self._do_clear_send) self.clear_send_button = None if not self.touch_mode: if self.clear_mode: if self.send_control is not None: self.send_control.remove_value_listener(self._do_clear_send) self.send_control = None if self._volume_control is not None: self._volume_control.remove_value_listener(self._do_clear_vol) self._volume_control = None if self._pan_control is not None: self._pan_control.remove_value_listener(self._do_clear_pan) self._pan_control = None super().disconnect()
def add_value_listener(self, callback, identify_sender=False): if not self._is_notifying: ButtonElement.add_value_listener(self, callback, identify_sender) else: self._pending_listeners.append((callback, identify_sender))
class LaunchMod(Launchpad): def __init__(self, *a, **k): ControlSurface.__init__(self, *a, **k) with self.component_guard(): self._monomod_version = 'b996' self._host_name = 'LaunchMod' self._color_type = 'Launchpad' self._timer = 0 self._suppress_send_midi = True self._suppress_session_highlight = True self._suppress_highlight = False is_momentary = True self._suggested_input_port = 'Launchpad' self._suggested_output_port = 'Launchpad' self._control_is_with_automap = False self._user_byte_write_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 16) self._user_byte_write_button.name = 'User_Byte_Button' self._user_byte_write_button.send_value(1) self._user_byte_write_button.add_value_listener(self._user_byte_value) self._wrote_user_byte = False self._challenge = Live.Application.get_random_int(0, 400000000) & 2139062143 matrix = ButtonMatrixElement() matrix.name = 'Button_Matrix' for row in range(8): button_row = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column, str(column) + '_Clip_' + str(row) + '_Button', self) for column in range(8) ] matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0, optimized_send_midi=False) self._config_button.add_value_listener(self._config_value) top_button_names = ['Bank_Select_Up_Button', 'Bank_Select_Down_Button', 'Bank_Select_Left_Button', 'Bank_Select_Right_Button', 'Session_Button', 'User1_Button', 'User2_Button', 'Mixer_Button'] side_button_names = ['Vol_Button', 'Pan_Button', 'SndA_Button', 'SndB_Button', 'Stop_Button', 'Trk_On_Button', 'Solo_Button', 'Arm_Button'] top_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index, top_button_names[index], self) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], side_button_names[index], self) for index in range(8) ] self._side_buttons = ButtonMatrixElement() self._side_buttons.add_row(side_buttons) self._setup_monobridge() self._setup_mod() self._selector = MainSelectorComponent(self, matrix, tuple(top_buttons), tuple(side_buttons), self._config_button) self._selector.name = 'Main_Modes' for control in self.controls: isinstance(control, MonoButtonElement) and control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False self.log_message('--------------= ' + str(self._monomod_version) + ' log opened =--------------') """Mono overrides and additions""" def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_mod(self): self.monomodular = get_monomodular(self) self.monomodular.name = 'monomodular_switcher' self.modhandler = LaunchModHandler(self) self.modhandler.name = 'ModHandler' #self.modhandler.layer = Layer( lock_button = self._note_mode_button, push_grid = self._matrix, shift_button = self._shift_button, alt_button = self._select_button, key_buttons = self._track_state_buttons) #self.modhandler.layer.priority = 4 #self.modhandler.nav_buttons_layer = AddLayerMode( self.modhandler, Layer(nav_up_button = self._nav_up_button, nav_down_button = self._nav_down_button, nav_left_button = self._nav_left_button, nav_right_button = self._nav_right_button) ) def update_display(self): ControlSurface.update_display(self) self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if self.modhandler.is_enabled(): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer) def disconnect(self): super(LaunchMod, self).disconnect() rebuild_sys()
class Oxygen_3rd_Gen(ControlSurface): def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): is_momentary = True self._suggested_input_port = 'Oxygen' self._suggested_output_port = 'Oxygen' self._has_slider_section = True self._shift_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 57) self._shift_button.add_value_listener(self._shift_value) self._mixer = SpecialMixerComponent(NUM_TRACKS) self._mute_solo_buttons = [] self._track_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 111) self._track_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 110) self._master_slider = SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 41) for index in range(NUM_TRACKS): self._mute_solo_buttons.append( ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 49 + index)) self._mixer.channel_strip(index).set_volume_control( SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 33 + index)) self._shift_value(0) self._mixer.master_strip().set_volume_control(self._master_slider) self._mixer.selected_strip().set_volume_control(None) device = DeviceComponent( device_selection_follows_track_selection=True) device.set_parameter_controls( tuple([ EncoderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 17 + index, Live.MidiMap.MapMode.absolute) for index in range(8) ])) self.set_device_component(device) ffwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 115) rwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 114) loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 113) transport = TransportComponent() transport.set_stop_button( ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 116)) transport.set_play_button( ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 117)) transport.set_record_button( ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 118)) session = SessionComponent(0, 0) transport_view_modes = TransportViewModeSelector( transport, session, ffwd_button, rwd_button, loop_button) def disconnect(self): self._shift_button.remove_value_listener(self._shift_value) self._shift_button = None ControlSurface.disconnect(self) def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._send_midi, IDENTITY_REQUEST) def handle_sysex(self, midi_bytes): if midi_bytes[0:5] == IDENTITY_RESPONSE: if midi_bytes[10] == 38: self._mixer.master_strip().set_volume_control(None) self._mixer.selected_strip().set_volume_control( self._master_slider) def _shift_value(self, value): for index in range(NUM_TRACKS): if value == 0: self._mixer.channel_strip(index).set_solo_button(None) self._mixer.channel_strip(index).set_mute_button( self._mute_solo_buttons[index]) self._mixer.set_bank_buttons(None, None) self._mixer.set_select_buttons(self._track_up_button, self._track_down_button) else: self._mixer.channel_strip(index).set_mute_button(None) self._mixer.channel_strip(index).set_solo_button( self._mute_solo_buttons[index]) self._mixer.set_select_buttons(None, None) self._mixer.set_bank_buttons(self._track_up_button, self._track_down_button)
class Novation_Impulse(ControlSurface): def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.set_pad_translations(PAD_TRANSLATIONS) self._suggested_input_port = 'Impulse' self._suggested_output_port = 'Impulse' self._has_sliders = True self._current_midi_map = None self._display_reset_delay = -1 self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 39) self._preview_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 41) self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 8) self._shift_button.name = 'Shift_Button' self._master_slider.name = 'Master_Volume_Control' self._master_slider.add_value_listener((self._slider_value), identify_sender=True) self._preview_button.add_value_listener(self._preview_value) self._setup_mixer() self._setup_session() self._setup_transport() self._setup_device() self._setup_name_display() device_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 10) mixer_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 9) device_button.name = 'Encoder_Device_Mode' mixer_button.name = 'Encoder_Mixer_Mode' self._encoder_modes = EncoderModeSelector(self._device_component, self._mixer, self._next_bank_button, self._prev_bank_button, self._encoders) self._encoder_modes.set_device_mixer_buttons( device_button, mixer_button) self._string_to_display = None for component in self.components: component.set_enabled(False) def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(3, self._send_midi, SYSEX_START + (6, 1, 1, 1, 247)) def handle_sysex(self, midi_bytes): if midi_bytes[0:-2] == SYSEX_START + (7, ): if midi_bytes[(-2)] != 0: self._has_sliders = midi_bytes[(-2)] != 25 self.schedule_message(1, self._show_startup_message) for control in self.controls: if isinstance(control, InputControlElement): control.clear_send_cache() for component in self.components: component.set_enabled(True) if self._has_sliders: self._mixer.master_strip().set_volume_control( self._master_slider) self._mixer.update() else: self._mixer.master_strip().set_volume_control(None) self._mixer.selected_strip().set_volume_control( self._master_slider) for index in range(len(self._sliders)): self._mixer.channel_strip(index).set_volume_control( None) slider = self._sliders[index] slider.release_parameter() if slider.value_has_listener(self._slider_value): slider.remove_value_listener(self._slider_value) self._encoder_modes.set_provide_volume_mode( not self._has_sliders) self.request_rebuild_midi_map() def disconnect(self): self._name_display_data_source.set_display_string(' ') for encoder in self._encoders: encoder.remove_value_listener(self._encoder_value) self._master_slider.remove_value_listener(self._slider_value) if self._has_sliders: for slider in tuple(self._sliders): slider.remove_value_listener(self._slider_value) for button in self._strip_buttons: button.remove_value_listener(self._mixer_button_value) self._preview_button.remove_value_listener(self._preview_value) ControlSurface.disconnect(self) self._encoders = None self._sliders = None self._strip_buttons = None self._master_slider = None self._current_midi_map = None self._shift_button = None self._name_display = None self._prev_bank_button = None self._next_bank_button = None self._encoder_modes = None self._transport_view_modes = None self._send_midi(SYSEX_START + (6, 0, 0, 0, 247)) def build_midi_map(self, midi_map_handle): self._current_midi_map = midi_map_handle ControlSurface.build_midi_map(self, midi_map_handle) def update_display(self): ControlSurface.update_display(self) if self._string_to_display != None: self._name_display_data_source.set_display_string( self._string_to_display) self._string_to_display = None if self._display_reset_delay >= 0: self._display_reset_delay -= 1 if self._display_reset_delay == -1: self._show_current_track_name() def _setup_mixer(self): mute_solo_flip_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 34) self._next_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 37) self._prev_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 38) self._strip_buttons = [] mute_solo_flip_button.name = 'Mute_Solo_Flip_Button' self._next_nav_button.name = 'Next_Track_Button' self._prev_nav_button.name = 'Prev_Track_Button' self._mixer = SpecialMixerComponent(8) self._mixer.name = 'Mixer' self._mixer.set_select_buttons(self._next_nav_button, self._prev_nav_button) self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.master_strip().set_volume_control(self._master_slider) self._sliders = [] for index in range(8): strip = self._mixer.channel_strip(index) strip.name = 'Channel_Strip_' + str(index) strip.set_invert_mute_feedback(True) self._sliders.append(SliderElement(MIDI_CC_TYPE, 0, index)) self._sliders[(-1)].name = str(index) + '_Volume_Control' self._sliders[(-1)].set_feedback_delay(-1) self._sliders[(-1)].add_value_listener((self._slider_value), identify_sender=True) strip.set_volume_control(self._sliders[(-1)]) self._strip_buttons.append( ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 9 + index)) self._strip_buttons[(-1)].name = str(index) + '_Mute_Button' self._strip_buttons[(-1)].add_value_listener( (self._mixer_button_value), identify_sender=True) self._mixer.master_strip().set_mute_button( ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 17)) self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons), mute_solo_flip_button) def _setup_session(self): num_pads = len(PAD_TRANSLATIONS) self._track_left_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 36) self._track_right_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 35) self._session = SessionComponent(8, 0) self._session.name = 'Session_Control' self._session.selected_scene().name = 'Selected_Scene' self._session.set_mixer(self._mixer) self._session.set_page_left_button(self._track_left_button) self._session.set_page_right_button(self._track_right_button) pads = [] for index in range(num_pads): pads.append( ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 60 + index)) pads[(-1)].name = 'Pad_' + str(index) clip_slot = self._session.selected_scene().clip_slot(index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.set_launch_button(pads[(-1)]) clip_slot.name = str(index) + '_Selected_Clip_Slot' def _setup_transport(self): rwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 27) ffwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 28) stop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 29) play_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 30) loop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 31) rec_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 32) ffwd_button.name = 'FFwd_Button' rwd_button.name = 'Rwd_Button' loop_button.name = 'Loop_Button' play_button.name = 'Play_Button' stop_button.name = 'Stop_Button' rec_button.name = 'Record_Button' transport = ShiftableTransportComponent() transport.name = 'Transport' transport.set_stop_button(stop_button) transport.set_play_button(play_button) transport.set_record_button(rec_button) transport.set_shift_button(self._shift_button) self._transport_view_modes = TransportViewModeSelector( transport, self._session, ffwd_button, rwd_button, loop_button) self._transport_view_modes.name = 'Transport_View_Modes' def _setup_device(self): encoders = [] for index in range(8): encoders.append( PeekableEncoderElement( MIDI_CC_TYPE, 1, index, Live.MidiMap.MapMode.relative_binary_offset)) encoders[(-1)].set_feedback_delay(-1) encoders[(-1)].add_value_listener((self._encoder_value), identify_sender=True) encoders[(-1)].name = 'Device_Control_' + str(index) self._encoders = tuple(encoders) self._prev_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 12) self._next_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 11) self._prev_bank_button.name = 'Device_Bank_Down_Button' self._next_bank_button.name = 'Device_Bank_Up_Button' device = DeviceComponent(device_selection_follows_track_selection=True) device.name = 'Device_Component' self.set_device_component(device) device.set_parameter_controls(self._encoders) device.set_bank_nav_buttons(self._prev_bank_button, self._next_bank_button) def _setup_name_display(self): self._name_display = PhysicalDisplayElement(16, 1) self._name_display.name = 'Display' self._name_display.set_message_parts(SYSEX_START + (8, ), (247, )) self._name_display_data_source = DisplayDataSource() self._name_display.segment(0).set_data_source( self._name_display_data_source) def _encoder_value(self, value, sender): if self._device_component.is_enabled(): display_string = ' - ' if sender.mapped_parameter() != None: display_string = sender.mapped_parameter().name self._set_string_to_display(display_string) def _slider_value(self, value, sender): if self._mixer.is_enabled(): display_string = ' - ' if sender.mapped_parameter() != None: master = self.song().master_track tracks = self.song().tracks returns = self.song().return_tracks track = None if sender == self._master_slider: if self._has_sliders: track = master else: track = self.song().view.selected_track else: track = self._mixer.channel_strip( self._sliders.index(sender))._track if track == master: display_string = 'Master' else: pass if track in tracks: display_string = str(list(tracks).index(track) + 1) elif track in returns: display_string = str( chr(ord('A') + list(returns).index(track))) else: pass display_string += ' Volume' self._set_string_to_display(display_string) def _mixer_button_value(self, value, sender): if self._mixer.is_enabled(): if value > 0: strip = self._mixer.channel_strip( self._strip_buttons.index(sender)) if strip != None: self._string_to_display = None self._name_display.segment(0).set_data_source( strip.track_name_data_source()) self._name_display.update() self._display_reset_delay = STANDARD_DISPLAY_DELAY else: self._set_string_to_display(' - ') def _preview_value(self, value): for encoder in self._encoders: encoder.set_peek_mode(value > 0) def _show_current_track_name(self): if self._name_display != None: if self._mixer != None: self._string_to_display = None self._name_display.segment(0).set_data_source( self._mixer.selected_strip().track_name_data_source()) self._name_display.update() def _show_startup_message(self): self._name_display.display_message('LIVE') self._display_reset_delay = INITIAL_DISPLAY_DELAY def _set_string_to_display(self, string_to_display): self._name_display.segment(0).set_data_source( self._name_display_data_source) self._string_to_display = string_to_display self._display_reset_delay = STANDARD_DISPLAY_DELAY def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) self._show_current_track_name() if not self._has_sliders: all_tracks = self._session.tracks_to_use() selected_track = self.song().view.selected_track num_strips = self._session.width() if selected_track in all_tracks: track_index = list(all_tracks).index(selected_track) new_offset = track_index - track_index % num_strips self._session.set_offsets(new_offset, self._session.scene_offset())
class Axiom_DirectLink(ControlSurface): def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.set_pad_translations(PAD_TRANSLATIONS) self._suggested_input_port = 'DirectLink' self._suggested_output_port = 'DirectLink' self._waiting_for_first_response = True self._has_sliders = True self._current_midi_map = None self._display_reset_delay = -1 self._shift_pressed = False self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 13) self._master_slider = SliderElement(MIDI_CC_TYPE, 15, 41) self._next_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 111) self._prev_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 110) self._device_bank_buttons = None self._device_navigation = None self._shift_button.name = 'Shift_Button' self._master_slider.name = 'Master_Volume_Control' self._next_nav_button.name = 'Next_Track_Button' self._prev_nav_button.name = 'Prev_Track_Button' self._master_slider.add_value_listener((self._slider_value), identify_sender=True) self._shift_button.add_value_listener(self._shift_value) self._setup_mixer() self._setup_transport_and_session() self._setup_device() self._setup_display() for component in self.components: component.set_enabled(False) def refresh_state(self): ControlSurface.refresh_state(self) self._waiting_for_first_response = True self.schedule_message(3, self._send_midi, SYSEX_START + (32, 46, 247)) def handle_sysex(self, midi_bytes): if midi_bytes[0:-2] == SYSEX_START + (32, ): if midi_bytes[(-2)] != 0: self._has_sliders = midi_bytes[(-2)] & 8 != 0 if self._waiting_for_first_response: self._waiting_for_first_response = False self.schedule_message(1, self._show_startup_message) for component in self.components: component.set_enabled(True) if self._has_sliders: self._mixer.master_strip().set_volume_control( self._master_slider) self._mixer.update() else: self._mixer.master_strip().set_volume_control(None) self._mixer.selected_strip().set_volume_control( self._master_slider) self.request_rebuild_midi_map() def disconnect(self): self._display_data_source.set_display_string(' ') self._shift_button.remove_value_listener(self._shift_value) self._inst_button.remove_value_listener(self._inst_value) for encoder in self._encoders: encoder.remove_value_listener(self._encoder_value) for slider in tuple(self._sliders) + (self._master_slider, ): slider.remove_value_listener(self._slider_value) for button in tuple( self._strip_buttons) + (self._selected_mute_solo_button, ): button.remove_value_listener(self._mixer_button_value) for button in self._device_bank_buttons: button.remove_value_listener(self._device_bank_value) self._encoders = None self._sliders = None self._strip_buttons = None self._master_slider = None self._current_midi_map = None self._selected_mute_solo_button = None self._inst_button = None self._shift_button = None self._device_navigation = None self._display = None ControlSurface.disconnect(self) self._send_midi(SYSEX_START + (32, 0, 247)) def build_midi_map(self, midi_map_handle): self._current_midi_map = midi_map_handle ControlSurface.build_midi_map(self, midi_map_handle) def update_display(self): ControlSurface.update_display(self) if self._display_reset_delay >= 0: self._display_reset_delay -= 1 if self._display_reset_delay == -1: self._show_current_track_name() def _setup_mixer(self): self._selected_mute_solo_button = ButtonElement( IS_MOMENTARY, MIDI_CC_TYPE, 15, 12) mute_solo_flip_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 57) self._strip_buttons = [] self._selected_mute_solo_button.name = 'Selected_Mute_Button' mute_solo_flip_button.name = 'Mute_Solo_Flip_Button' self._selected_mute_solo_button.add_value_listener( (self._mixer_button_value), identify_sender=True) self._mixer = ShiftableMixerComponent(8) self._mixer.name = 'Mixer' self._mixer.set_shift_button(self._shift_button) self._mixer.set_selected_mute_solo_button( self._selected_mute_solo_button) self._mixer.set_select_buttons(self._next_nav_button, self._prev_nav_button) self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.master_strip().set_volume_control(self._master_slider) self._sliders = [] for index in range(8): strip = self._mixer.channel_strip(index) strip.name = 'Channel_Strip_' + str(index) strip.set_invert_mute_feedback(True) self._sliders.append(SliderElement(MIDI_CC_TYPE, 15, 33 + index)) self._sliders[(-1)].name = str(index) + '_Volume_Control' self._sliders[(-1)].set_feedback_delay(-1) self._sliders[(-1)].add_value_listener((self._slider_value), identify_sender=True) strip.set_volume_control(self._sliders[(-1)]) self._strip_buttons.append( ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 49 + index)) self._strip_buttons[(-1)].name = str(index) + '_Mute_Button' self._strip_buttons[(-1)].add_value_listener( (self._mixer_button_value), identify_sender=True) self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons), mute_solo_flip_button) def _setup_transport_and_session(self): ffwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 115) rwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 114) loop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 113) play_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 117) stop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 116) rec_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 118) ffwd_button.name = 'FFwd_Button' rwd_button.name = 'Rwd_Button' loop_button.name = 'Loop_Button' play_button.name = 'Play_Button' stop_button.name = 'Stop_Button' rec_button.name = 'Record_Button' transport = ShiftableTransportComponent() transport.name = 'Transport' transport.set_shift_button(self._shift_button) transport.set_stop_button(stop_button) transport.set_play_button(play_button) transport.set_record_button(rec_button) pads = [] for index in range(len(PAD_TRANSLATIONS)): pads.append( ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 15, PAD_TRANSLATIONS[index][2])) pads[(-1)].name = 'Pad_' + str(index) self._session = ShiftableSessionComponent(8, 0) self._session.name = 'Session_Control' self._session.selected_scene().name = 'Selected_Scene' self._session.set_mixer(self._mixer) self._session.set_shift_button(self._shift_button) self._session.set_clip_slot_buttons(tuple(pads)) transport_view_modes = TransportViewModeSelector( transport, self._session, ffwd_button, rwd_button, loop_button) transport_view_modes.name = 'Transport_View_Modes' def _setup_device(self): self._encoders = [] for offset in range(8): self._encoders.append( PeekableEncoderElement( MIDI_CC_TYPE, 15, 17 + offset, Live.MidiMap.MapMode.relative_smooth_two_compliment)) self._encoders[(-1)].set_feedback_delay(-1) self._encoders[(-1)].add_value_listener((self._encoder_value), identify_sender=True) self._encoders[(-1)].name = 'Device_Control_' + str(offset) prev_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 14) next_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 15) prev_bank_button.name = 'Device_Bank_Down_Button' next_bank_button.name = 'Device_Bank_Up_Button' device = BestBankDeviceComponent( device_selection_follows_track_selection=True) device.name = 'Device_Component' self.set_device_component(device) device.set_parameter_controls(tuple(self._encoders)) device.set_bank_nav_buttons(prev_bank_button, next_bank_button) self._device_bank_buttons = (prev_bank_button, next_bank_button) prev_bank_button.add_value_listener(self._device_bank_value) next_bank_button.add_value_listener(self._device_bank_value) self._inst_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15, 109) self._inst_button.name = 'Inst_Button' self._inst_button.add_value_listener(self._inst_value) self._device_navigation = DetailViewCntrlComponent() self._device_navigation.name = 'Device_Navigation_Component' def _setup_display(self): self._display = PhysicalDisplayElement(5, 1) self._display.name = 'Display' self._display.set_message_parts(SYSEX_START + (17, 1, 0, 0), (247, )) self._display_data_source = DisplayDataSource() self._display.segment(0).set_data_source(self._display_data_source) def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) self._show_current_track_name() def _shift_value(self, value): self._shift_pressed = value > 0 for encoder in self._encoders: encoder.set_peek_mode(self._shift_pressed) if self._shift_pressed: self._mixer.set_select_buttons(None, None) self._session.set_track_bank_buttons(self._next_nav_button, self._prev_nav_button) self._device_component.set_bank_nav_buttons(None, None) self._device_navigation.set_device_nav_buttons( self._device_bank_buttons[0], self._device_bank_buttons[1]) else: self._session.set_track_bank_buttons(None, None) self._mixer.set_select_buttons(self._next_nav_button, self._prev_nav_button) self._device_navigation.set_device_nav_buttons(None, None) self._device_component.set_bank_nav_buttons( self._device_bank_buttons[0], self._device_bank_buttons[1]) self.request_rebuild_midi_map() def _encoder_value(self, value, sender): if self._device_component.is_enabled(): display_string = ' - ' if sender.mapped_parameter() != None: display_string = sender.mapped_parameter().name self._display_data_source.set_display_string(display_string) self._set_display_data_source(self._display_data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY def _slider_value(self, value, sender): if self._mixer.is_enabled(): display_string = ' - ' if sender.mapped_parameter() != None: master = self.song().master_track tracks = self.song().tracks returns = self.song().return_tracks track = None if sender == self._master_slider: if self._has_sliders: track = master else: track = self.song().view.selected_track else: track = self._mixer.channel_strip( self._sliders.index(sender))._track if track == master: display_string = 'Ma' else: pass if track in tracks: display_string = str(list(tracks).index(track) + 1) elif track in returns: display_string = str( chr(ord('A') + list(returns).index(track))) else: pass display_string += ' Vol' self._display_data_source.set_display_string(display_string) self._set_display_data_source(self._display_data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY def _mixer_button_value(self, value, sender): if self._mixer.is_enabled(): if value > 0: strip = None if sender == self._selected_mute_solo_button: strip = self._mixer.selected_strip() else: strip = self._mixer.channel_strip( self._strip_buttons.index(sender)) if strip != None: self._set_display_data_source( strip.track_name_data_source()) else: self._display_data_source.set_display_string(' - ') self._set_display_data_source(self._display_data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY def _device_bank_value(self, value): if self._device_component.is_enabled(): if value > 0: data_source = self._device_component.bank_name_data_source() if self._shift_pressed: data_source = self._device_component.device_name_data_source( ) self._set_display_data_source(data_source) self._display_reset_delay = STANDARD_DISPLAY_DELAY def _inst_value(self, value): if value > 0: if self._device_component.is_enabled(): if self.song().view.selected_track.view.select_instrument(): self._set_display_data_source( self._device_component.device_name_data_source()) self._display_reset_delay = STANDARD_DISPLAY_DELAY def _show_current_track_name(self): if self._display != None: if self._mixer != None: self._set_display_data_source( self._mixer.selected_strip().track_name_data_source()) def _show_startup_message(self): self._display.display_message('LIVE') self._display_reset_delay = INITIAL_DISPLAY_DELAY def _set_display_data_source(self, data_source): self._display.segment(0).set_data_source(data_source) data_source.update()