def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._monomod_version = 'b994' self.hosts = [] self._host_name = 'BlockPad' self._color_type = 'Monochrome' self._timer = 0 is_momentary = True self._suggested_input_port = 'block (Controls)' self._suggested_output_port = 'block (Controls)' self._wrote_user_byte = False matrix = ButtonMatrixElement() for row in range(8): button_row = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((column * 8) + row), 'Button_'+str(column)+'_'+str(row), self) for column in range(8) ] matrix.add_row(tuple(button_row)) knobs = [ EncoderElement(MIDI_CC_TYPE, 0, KNOB_CC[index], Live.MidiMap.MapMode.absolute) for index in range(8) ] sliders = [ EncoderElement(MIDI_CC_TYPE, 0, SLIDER_CC[index], Live.MidiMap.MapMode.absolute) for index in range(2) ] self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0) self._config_button.add_value_listener(self._config_value) top_buttons = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, TOP_NOTES[index], 'Top_Button'+str(index), self) for index in range(8) ] side_buttons = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], 'Side_Button'+str(index), self) for index in range(8) ] self._setup_monobridge() self._setup_monomod() self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, tuple(knobs), tuple(sliders), self) self._user_byte_write_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 16) self._user_byte_value(1) self._user_byte_write_button.add_value_listener(self._user_byte_value) self.set_enabled(True) self.log_message("--------------= BlockPad log opened =--------------") #Create entry in log file self.refresh_state()
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._monomod_version = 'b994' self._host_name = 'LaunchMod' self._color_type = 'Launchpad' self.hosts = [] self._timer = 0 self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True is_momentary = True self._suggested_input_port = 'Launchpad' self._suggested_output_port = 'Launchpad' self._wrote_user_byte = False self._control_is_with_automap = False self._challenge = (Live.Application.get_random_int(0, 400000000) & 2139062143) matrix = ButtonMatrixElement() matrix.name = 'ButtonMatrix' for row in range(8): #button_row = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column)) for column in range(8) ] button_row = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column), 'Button_' + str(row) + '_' + str(column), self) for column in range(8) ] matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0) self._config_button.add_value_listener(self._config_value) top_buttons = [ FlashingButtonElement(is_momentary, MIDI_CC_TYPE, 0, (104 + index), 'Top_Button' + str(index), self) for index in range(8) ] side_buttons = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], 'Side_Button' + str(index), self) for index in range(8) ] self._setup_monobridge() self._setup_monomod() self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._suppress_session_highlight = False self._suppress_send_midi = False self._user_byte_write_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 16) self._user_byte_write_button.send_value(1) self._user_byte_write_button.add_value_listener(self._user_byte_value) self._suppress_send_midi = True self.set_suppress_rebuild_requests(False) self.log_message("--------------= LaunchMod log opened =--------------" ) #Create entry in log file self.refresh_state()
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True 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 = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) 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_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button) self._selector.name = 'Main_Modes' for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True 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 = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) 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_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._selector.name = 'Main_Modes' self._do_combine() for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False #self.set_suppress_rebuild_requests(False) self.log_message("LaunchPad95 Loaded !")
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True 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 = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column)) button.name = (((str(column) + "_Clip_") + str(row)) + "_Button") button_row.append(button) matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0) self._config_button.add_value_listener(self._config_value) top_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, (104 + index)) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = "Bank_Select_Up_Button" top_buttons[1].name = "Bank_Select_Down_Button" top_buttons[2].name = "Bank_Select_Left_Button" top_buttons[3].name = "Bank_Select_Right_Button" top_buttons[4].name = "Session_Button" top_buttons[5].name = "User1_Button" top_buttons[6].name = "User2_Button" top_buttons[7].name = "Mixer_Button" side_buttons[0].name = "Vol_Button" side_buttons[1].name = "Pan_Button" side_buttons[2].name = "SndA_Button" side_buttons[3].name = "SndB_Button" side_buttons[4].name = "Stop_Button" side_buttons[5].name = "Trk_On_Button" side_buttons[6].name = "Solo_Button" side_buttons[7].name = "Arm_Button" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._selector.name = "Main_Modes" for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self._suppress_session_highlight = False self.set_suppress_rebuild_requests(False) self.log_message("LaunchPad85 Loaded !")
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._monomod_version = 'b995' self._host_name = 'LaunchMod' self._color_type = 'Launchpad' self.hosts = [] 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._setup_monobridge() self._setup_monomod() self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._selector.name = 'Main_Modes' for control in self.controls: if isinstance(control, MonoButtonElement): 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 =--------------") #Create entry in log file
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._monomod_version = 'b994' self._host_name = 'LaunchMod' self._color_type = 'Launchpad' self.hosts = [] self._timer = 0 self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True is_momentary = True self._suggested_input_port = 'Launchpad' self._suggested_output_port = 'Launchpad' self._wrote_user_byte = False self._control_is_with_automap = False self._challenge = (Live.Application.get_random_int(0, 400000000) & 2139062143) matrix = ButtonMatrixElement() matrix.name = 'ButtonMatrix' for row in range(8): #button_row = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column)) for column in range(8) ] button_row = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column), 'Button_'+str(row)+'_'+str(column), self) for column in range(8) ] matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0) self._config_button.add_value_listener(self._config_value) top_buttons = [ FlashingButtonElement(is_momentary, MIDI_CC_TYPE, 0, (104 + index), 'Top_Button'+str(index), self) for index in range(8) ] side_buttons = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], 'Side_Button'+str(index), self) for index in range(8) ] self._setup_monobridge() self._setup_monomod() self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._suppress_session_highlight = False self._suppress_send_midi = False self._user_byte_write_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 16) self._user_byte_write_button.send_value(1) self._user_byte_write_button.add_value_listener(self._user_byte_value) self._suppress_send_midi = True self.set_suppress_rebuild_requests(False) self.log_message("--------------= LaunchMod log opened =--------------") #Create entry in log file self.refresh_state()
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._monomod_version = 'b995' self._host_name = 'LaunchMod' self._color_type = 'Launchpad' self.hosts = [] 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._setup_monobridge() self._setup_monomod() self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._selector.name = 'Main_Modes' for control in self.controls: if isinstance(control, MonoButtonElement): 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 =--------------") #Create entry in log file
class LaunchMod(ControlSurface): """ Script for Novation's Launchpad Controller """ def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._monomod_version = 'b995' self._host_name = 'LaunchMod' self._color_type = 'Launchpad' self.hosts = [] 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._setup_monobridge() self._setup_monomod() self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._selector.name = 'Main_Modes' for control in self.controls: if isinstance(control, MonoButtonElement): 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 =--------------") #Create entry in log file def allow_updates(self, allow_updates): for component in self.components: component.set_allow_update(int(allow_updates != 0)) def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._selector = None self._user_byte_write_button.remove_value_listener( self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): if len(midi_bytes) == 8: if midi_bytes[1:5] == (0, 32, 41, 6): response = long(midi_bytes[5]) response += long(midi_bytes[6]) << 8 if response == Live.Application.encrypt_challenge2( self._challenge): self._suppress_send_midi = False self.set_enabled(True) def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if self._selector.mode_index == 1: new_channel = self._selector.channel_for_current_mode() for note in DRUM_NOTES: self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) def _send_midi(self, midi_bytes, optimized=None): sent_successfully = False if not self._suppress_send_midi: sent_successfully = ControlSurface._send_midi(self, midi_bytes, optimized=optimized) return sent_successfully def _update_hardware(self): self._suppress_send_midi = False self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() def _send_challenge(self): for index in range(4): challenge_byte = self._challenge >> 8 * index & 127 self._send_midi((176, 17 + index, challenge_byte)) def _user_byte_value(self, value): assert value in range(128) enabled = self._wrote_user_byte or value == 1 self._control_is_with_automap = not enabled self._suppress_send_midi = self._control_is_with_automap if not self._control_is_with_automap: for control in self.controls: if isinstance(control, MonoButtonElement): control.set_force_next_value() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False def _button_value(self, value): assert value in range(128) def _config_value(self, value): assert value in range(128) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if not self._suppress_session_highlight: ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks) def _setup_m4l_interface(self): self._m4l_interface = M4LInterfaceComponent( controls=self.controls, component_guard=self.component_guard) self.get_control_names = self._m4l_interface.get_control_names self.get_control = self._m4l_interface.get_control self.grab_control = self._m4l_interface.grab_control self.release_control = self._m4l_interface.release_control """Mono overrides and additions""" def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_monomod(self): self._host = MonomodComponent(self) self._host.name = 'Monomod_Host' self.hosts = [self._host] def update_display(self): ControlSurface.update_display(self) self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if self._host.is_enabled(): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer)
def __init__(self, c_instance): live = Live.Application.get_application() self._live_major_version = live.get_major_version() self._live_minor_version = live.get_minor_version() self._live_bugfix_version = live.get_bugfix_version() self._mk2_rgb = Settings.DEVICE == 'Launchpad mk2' if self._mk2_rgb: self._skin = Skin('launchpad mk2') self._side_notes = (89, 79, 69, 59, 49, 39, 29, 19) self._drum_notes = (20, 30, 31, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126) else: self._skin = Skin('launchpad') self._side_notes = (8, 24, 40, 56, 72, 88, 104, 120) self._drum_notes = (41, 42, 43, 44, 45, 46, 47, 57, 58, 59, 60, 61, 62, 63, 73, 74, 75, 76, 77, 78, 79, 89, 90, 91, 92, 93, 94, 95, 105, 106, 107) ControlSurface.__init__(self, c_instance) with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True is_momentary = True if self._mk2_rgb: self._suggested_input_port = ("Launchpad", "Launchpad Mini", "Launchpad S") self._suggested_output_port = ("Launchpad", "Launchpad Mini", "Launchpad S") else: self._suggested_input_port = "Launchpad MK2" self._suggested_output_port = "Launchpad MK2" 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 = [] for column in range(8): if self._mk2_rgb: # for mk2 buttons are assigned "top to bottom" midi_note = (81 - (10 * row)) + column else: midi_note = row * 16 + column button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, midi_note, self._skin.off) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) 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_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index, self._skin.off) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, self._side_notes[index], self._skin.off) for index in range(8) ] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._osd = M4LInterface() self._osd.name = "OSD" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self._osd, self) self._selector.name = 'Main_Modes' self._do_combine() for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component( self._selector.session_component()) self._suppress_session_highlight = False self.log_message("LaunchPad95 Loaded !")
class Launchpad(ControlSurface): """ Script for Novation's Launchpad Controller """ def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True 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 = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) 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_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button) self._selector.name = 'Main_Modes' for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component( self._selector.session_component()) self._suppress_session_highlight = False def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._selector = None self._user_byte_write_button.remove_value_listener( self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None return def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): if len(midi_bytes) == 8: if midi_bytes[1:5] == (0, 32, 41, 6): response = long(midi_bytes[5]) response += long(midi_bytes[6]) << 8 if response == Live.Application.encrypt_challenge2( self._challenge): self._on_handshake_successful() def _on_handshake_successful(self): self._suppress_send_midi = False self.set_enabled(True) def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if self._selector.mode_index == 1: new_channel = self._selector.channel_for_current_mode() for note in DRUM_NOTES: self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) def _send_midi(self, midi_bytes, optimized=None): sent_successfully = False if not self._suppress_send_midi: sent_successfully = ControlSurface._send_midi(self, midi_bytes, optimized=optimized) return sent_successfully def _update_hardware(self): self._suppress_send_midi = False self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() def _send_challenge(self): for index in range(4): challenge_byte = self._challenge >> 8 * index & 127 self._send_midi((176, 17 + index, challenge_byte)) def _user_byte_value(self, value): if not value in range(128): raise AssertionError enabled = self._wrote_user_byte or value == 1 self._control_is_with_automap = not enabled self._suppress_send_midi = self._control_is_with_automap if not self._control_is_with_automap: for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.set_force_next_value() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False else: self._wrote_user_byte = False def _button_value(self, value): raise value in range(128) or AssertionError def _config_value(self, value): raise value in range(128) or AssertionError def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if not self._suppress_session_highlight: ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)
class APCmini(ControlSurface): """ Script for Novation's Launchpad Controller """ def __init__(self, c_instance): live = Live.Application.get_application() self._live_major_version = live.get_major_version() self._live_minor_version = live.get_minor_version() self._live_bugfix_version = live.get_bugfix_version() ControlSurface.__init__(self, c_instance) #self._device_selection_follows_track_selection = True with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True 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) # Apparently this CC is used to enable feedback, ie lighting up buttons that you pressed 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 = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (7-row) * 8 + column) # APCmini rows are in reverse order from Launchpad button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0, optimized_send_midi=False) # Control goes through here on LP, no real equivalent in APCmini (I don't think) self._config_button.add_value_listener(self._config_value) top_buttons = [ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 64 + index) for index in range(8)] side_buttons = [ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8)] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._osd = M4LInterface() self._osd.name = "OSD" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self._osd, self) self._selector.name = 'Main_Modes' self._do_combine() for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False self.log_message("LaunchPad95 Loaded !") def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._do_uncombine() self._selector = None self._user_byte_write_button.remove_value_listener(self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None _active_instances = [] #def highlighting_session_component(self): # " Return the session component showing the ring in Live session " # return self._selector.session_component() def _combine_active_instances(): support_devices = False for instance in APCmini._active_instances: support_devices |= (instance._device_component != None) offset = 0 for instance in APCmini._active_instances: instance._activate_combination_mode(offset, support_devices) offset += instance._selector._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def _activate_combination_mode(self, track_offset, support_devices): if(Settings.STEPSEQ__LINK_WITH_SESSION): self._selector._stepseq.link_with_step_offset(track_offset) if(Settings.SESSION__LINK): self._selector._session.link_with_track_offset(track_offset) def _do_combine(self): if (DO_COMBINE and (self not in APCmini._active_instances)): APCmini._active_instances.append(self) APCmini._combine_active_instances() def _do_uncombine(self): if self in APCmini._active_instances: APCmini._active_instances.remove(self) if(Settings.SESSION__LINK): self._selector._session.unlink() if(Settings.STEPSEQ__LINK_WITH_SESSION): self._selector._stepseq.unlink() APCmini._combine_active_instances() def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): # if len(midi_bytes) == 8: # if midi_bytes[1:5] == (0, 32, 41, 6): # response = long(midi_bytes[5]) # response += long(midi_bytes[6]) << 8 # if response == Live.Application.encrypt_challenge2(self._challenge): self._suppress_send_midi = False self.set_enabled(True) def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if self._selector.mode_index == 1: if self._selector._sub_mode_index[self._selector._mode_index] > 0: # disable midi map rebuild for instrument mode to prevent light feedback errors new_channel = self._selector.channel_for_current_mode() # self.log_message(str(new_channel)) # for note in DRUM_NOTES: # self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) def _send_midi(self, midi_bytes, optimized=None): sent_successfully = False if not self._suppress_send_midi: sent_successfully = ControlSurface._send_midi(self, midi_bytes, optimized=optimized) return sent_successfully def _update_hardware(self): self._suppress_send_midi = False self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False # self._send_challenge() self.set_enabled(True) # Enable anyways, without checking def _send_challenge(self): for index in range(4): challenge_byte = self._challenge >> 8 * index & 127 self._send_midi((176, 17 + index, challenge_byte)) def _user_byte_value(self, value): assert (value in range(128)) if not self._wrote_user_byte: enabled = (value == 1) self._control_is_with_automap = not enabled self._suppress_send_midi = self._control_is_with_automap if not self._control_is_with_automap: for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.set_force_next_value() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False else: self._wrote_user_byte = False def _button_value(self, value): assert value in range(128) def _config_value(self, value): assert value in range(128) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if not self._suppress_session_highlight: ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)
class Launchpad(ControlSurface): " SCRIPT FOR NOVATION'S LAUNCHPAD CONTROLLER " " INITALIZE " def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): #self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True 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" """ TRACKFINDER TEST track_index = 0 for track in self.song().tracks: if track_index < 8: button_row = [] if track.is_foldable: for column in range(8): log("right one: " + str(track_index)) button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((track_index * 16) + column)) #@UndefinedVariable button.name = (((str(column) + "_Clip_") + str(track_index)) + "_Button") button_row.append(button) track_index = track_index + 1 else: for column in range(8): log("wrong one: " + str(track_index)) button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99, True) #@UndefinedVariable button.name = (str(column) + "_Clip_Button-DUMMY") button_row.append(button) matrix.add_row(tuple(button_row)) log("done")""" """ ORIGINAL CODE """ for row in range(8): button_row = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column)) button.name = (((str(column) + "_Clip_") + str(row)) + "_Button") button_row.append(button) 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_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, (104 + index)) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = "Bank_Select_Up_Button" top_buttons[1].name = "Bank_Select_Down_Button" top_buttons[2].name = "Bank_Select_Left_Button" top_buttons[3].name = "Bank_Select_Right_Button" top_buttons[4].name = "Session_Button" top_buttons[5].name = "User1_Button" top_buttons[6].name = "User2_Button" top_buttons[7].name = "Mixer_Button" side_buttons[0].name = "Vol_Button" side_buttons[1].name = "Pan_Button" side_buttons[2].name = "SndA_Button" side_buttons[3].name = "SndB_Button" side_buttons[4].name = "Stop_Button" side_buttons[5].name = "Trk_On_Button" side_buttons[6].name = "Solo_Button" side_buttons[7].name = "Arm_Button" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button) self._selector.name = "Main_Modes" for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False #self.set_suppress_rebuild_requests(False) " DISCONNECTOR " def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._selector = None self._user_byte_write_button.remove_value_listener(self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None " RETURN THE SESSION COMPONENT SHOWING THE RING IN LIVE SESSION " def highlighting_session_component(self): return self._selector.session_component() " REFRESH " def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) " SYSEX HANDLING " def handle_sysex(self, midi_bytes): if (len(midi_bytes) == 8): if (midi_bytes[1:5] == (0, 32, 41, 6)): response = long(midi_bytes[5]) response += (long(midi_bytes[6]) << 8) if (response == Live.Application.encrypt_challenge2(self._challenge)): self._suppress_send_midi = False self.set_enabled(True) " MIDI MAP " def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if (self._selector.mode_index == 1): new_channel = self._selector.channel_for_current_mode() for note in DRUM_NOTES: self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) " SEND THE MIDI STUFF " def _send_midi(self, midi_bytes, optimized = None): sent_successfully = False if (not self._suppress_send_midi): sent_successfully = ControlSurface._send_midi(self, midi_bytes, optimized=optimized) return sent_successfully " UPDATE THE HARDWARE " def _update_hardware(self): self._suppress_send_midi = False self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() " CHALLANGE SEND " def _send_challenge(self): for index in range(4): challenge_byte = ((self._challenge >> (8 * index)) & 127) self._send_midi((176, (17 + index), challenge_byte)) " USER BYTE STUFF " def _user_byte_value(self, value): if not value in range(128): raise AssertionError enabled = self._wrote_user_byte or value == 1 self._control_is_with_automap = not enabled self._suppress_send_midi = self._control_is_with_automap if not self._control_is_with_automap: for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.set_force_next_value() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False else: self._wrote_user_byte = False " BUTTON VALUE " def _button_value(self, value): assert (value in range(128)) " CONFIG VALUE " def _config_value(self, value): assert (value in range(128)) " SET THE SESSION HIGHLIGHT " def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if (not self._suppress_session_highlight): ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)
def __init__(self, c_instance): live = Live.Application.get_application() self._live_major_version = live.get_major_version() self._live_minor_version = live.get_minor_version() self._live_bugfix_version = live.get_bugfix_version() self._mk2 = Settings.DEVICE == 'Launchpad mk2' if self._mk2: self._skin = Skin('Launchpad mk2') self._side_notes = (89, 79, 69, 59, 49, 39, 29, 19) self._drum_notes = (20, 30, 31, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126) else: self._skin = Skin('Launchpad') self._side_notes = (8, 24, 40, 56, 72, 88, 104, 120) self._drum_notes = (41, 42, 43, 44, 45, 46, 47, 57, 58, 59, 60, 61, 62, 63, 73, 74, 75, 76, 77, 78, 79, 89, 90, 91, 92, 93, 94, 95, 105, 106, 107) ControlSurface.__init__(self, c_instance) with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True is_momentary = True if self._mk2: self._suggested_input_port = 'Launchpad' self._suggested_output_port = 'Launchpad' else: self._suggested_input_port = 'Launchpad MK2' self._suggested_output_port = 'Launchpad MK2' 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 = [] for column in range(8): if self._mk2: # for mk2 buttons are assigned "top to bottom" midi_note = (81 - (10 * row)) + column else: midi_note = row * 16 + column button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, midi_note, self._skin.off) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) 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_buttons = [ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index, self._skin.off) for index in range(8)] side_buttons = [ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, self._side_notes[index], self._skin.off) for index in range(8)] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._osd = M4LInterface() self._osd.name = "OSD" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self._osd, self, self._skin) self._selector.name = 'Main_Modes' self._do_combine() for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False self.log_message("LaunchPad95 Loaded !")
class LaunchMod(ControlSurface): """ Script for Novation's Launchpad Controller """ def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._monomod_version = 'b995' self._host_name = 'LaunchMod' self._color_type = 'Launchpad' self.hosts = [] 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._setup_monobridge() self._setup_monomod() self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._selector.name = 'Main_Modes' for control in self.controls: if isinstance(control, MonoButtonElement): 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 =--------------") #Create entry in log file def allow_updates(self, allow_updates): for component in self.components: component.set_allow_update(int(allow_updates!=0)) def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._selector = None self._user_byte_write_button.remove_value_listener(self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): if len(midi_bytes) == 8: if midi_bytes[1:5] == (0, 32, 41, 6): response = long(midi_bytes[5]) response += long(midi_bytes[6]) << 8 if response == Live.Application.encrypt_challenge2(self._challenge): self._suppress_send_midi = False self.set_enabled(True) def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if self._selector.mode_index == 1: new_channel = self._selector.channel_for_current_mode() for note in DRUM_NOTES: self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) def _send_midi(self, midi_bytes, optimized = None): sent_successfully = False if not self._suppress_send_midi: sent_successfully = ControlSurface._send_midi(self, midi_bytes, optimized=optimized) return sent_successfully def _update_hardware(self): self._suppress_send_midi = False self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() def _send_challenge(self): for index in range(4): challenge_byte = self._challenge >> 8 * index & 127 self._send_midi((176, 17 + index, challenge_byte)) def _user_byte_value(self, value): assert value in range(128) enabled = self._wrote_user_byte or value == 1 self._control_is_with_automap = not enabled self._suppress_send_midi = self._control_is_with_automap if not self._control_is_with_automap: for control in self.controls: if isinstance(control, MonoButtonElement): control.set_force_next_value() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False def _button_value(self, value): assert value in range(128) def _config_value(self, value): assert value in range(128) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if not self._suppress_session_highlight: ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks) def _setup_m4l_interface(self): self._m4l_interface = M4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard) self.get_control_names = self._m4l_interface.get_control_names self.get_control = self._m4l_interface.get_control self.grab_control = self._m4l_interface.grab_control self.release_control = self._m4l_interface.release_control """Mono overrides and additions""" def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_monomod(self): self._host = MonomodComponent(self) self._host.name = 'Monomod_Host' self.hosts = [self._host] def update_display(self): ControlSurface.update_display(self) self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if self._host.is_enabled(): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer)
class Launchpad(ControlSurface): _active_instances = [] def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) live = Live.Application.get_application() self._live_major_version = live.get_major_version() self._live_minor_version = live.get_minor_version() self._live_bugfix_version = live.get_bugfix_version() self._selector = None #needed because update hardware is called. self._mk2_rgb = False with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True self._suggested_input_port = ("Launchpad", "Launchpad Mini", "Launchpad S", "Launchpad MK2") self._suggested_output_port = ("Launchpad", "Launchpad Mini", "Launchpad S", "Launchpad MK2") self._control_is_with_automap = False self._user_byte_write_button = None self._config_button = None self._wrote_user_byte = False self._challenge = Live.Application.get_random_int(0, 400000000) & 2139062143 self._init_done = False # caller will send challenge and we will continue as challenge is received. def init(self): #skip init if already done. if self._init_done: return self._init_done = True # second part of the __init__ after model has been identified using its challenge response if self._mk2_rgb: from SkinMK2 import make_skin self._skin = make_skin() self._side_notes = (89, 79, 69, 59, 49, 39, 29, 19) #self._drum_notes = (20, 30, 31, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126) self._drum_notes = (20, 30, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126) else: from SkinMK1 import make_skin self._skin = make_skin() self._side_notes = (8, 24, 40, 56, 72, 88, 104, 120) self._drum_notes = (41, 42, 43, 44, 45, 46, 47, 57, 58, 59, 60, 61, 62, 63, 73, 74, 75, 76, 77, 78, 79, 89, 90, 91, 92, 93, 94, 95, 105, 106, 107) with self.component_guard(): is_momentary = True self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0, optimized_send_midi=False) self._config_button.add_value_listener(self._config_value) self._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) matrix = ButtonMatrixElement() matrix.name = 'Button_Matrix' for row in range(8): button_row = [] for column in range(8): if self._mk2_rgb: # for mk2 buttons are assigned "top to bottom" midi_note = (81 - (10 * row)) + column else: midi_note = row * 16 + column button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, midi_note, skin = self._skin, control_surface = self) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) matrix.add_row(tuple(button_row)) top_buttons = [ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index, skin = self._skin) for index in range(8)] side_buttons = [ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, self._side_notes[index], skin = self._skin) for index in range(8)] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._osd = M4LInterface() self._osd.name = "OSD" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self._osd, self) self._selector.name = 'Main_Modes' self._do_combine() for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False # due to our 2 stage init, we need to rebuild midi map self.request_rebuild_midi_map() # and request update self._selector.update() if self._mk2_rgb: self.log_message("LaunchPad95 (mk2) Loaded !") else: self.log_message("LaunchPad95 Loaded !") def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._do_uncombine() if self._selector != None: self._user_byte_write_button.remove_value_listener(self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False if self._mk2_rgb: # launchpad mk2 needs disconnect string sent self._send_midi((240, 0, 32, 41, 2, 24, 64, 247)) if self._config_button != None: self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None def _combine_active_instances(): support_devices = False for instance in Launchpad._active_instances: support_devices |= (instance._device_component != None) offset = 0 for instance in Launchpad._active_instances: instance._activate_combination_mode(offset, support_devices) offset += instance._selector._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def _activate_combination_mode(self, track_offset, support_devices): if(Settings.STEPSEQ__LINK_WITH_SESSION): self._selector._stepseq.link_with_step_offset(track_offset) if(Settings.SESSION__LINK): self._selector._session.link_with_track_offset(track_offset) def _do_combine(self): if (DO_COMBINE and (self not in Launchpad._active_instances)): Launchpad._active_instances.append(self) Launchpad._combine_active_instances() def _do_uncombine(self): if self in Launchpad._active_instances: Launchpad._active_instances.remove(self) if(Settings.SESSION__LINK): self._selector._session.unlink() if(Settings.STEPSEQ__LINK_WITH_SESSION): self._selector._stepseq.unlink() Launchpad._combine_active_instances() def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): # MK2 has different challenge and params if len(midi_bytes) == 10 and midi_bytes[:7] == (240, 0, 32, 41, 2, 24, 64): response = long(midi_bytes[7]) response += long(midi_bytes[8]) << 8 if response == Live.Application.encrypt_challenge2(self._challenge): self._mk2_rgb = True self.log_message("Challenge Response ok (mk2)") self._suppress_send_midi = False self.set_enabled(True) self.init() #MK1 Challenge elif len(midi_bytes) == 8 and midi_bytes[1:5] == (0, 32, 41, 6): response = long(midi_bytes[5]) response += long(midi_bytes[6]) << 8 if response == Live.Application.encrypt_challenge2(self._challenge): self.log_message("Challenge Response ok (mk1)") self._mk2_rgb = False self.init() self._suppress_send_midi = False self.set_enabled(True) else: ControlSurface.handle_sysex(self,midi_bytes) def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if self._selector!=None: if self._selector._main_mode_index==2 or self._selector._main_mode_index==1: mode = Settings.USER_MODES[ (self._selector._main_mode_index-1) * 3 + self._selector._sub_mode_index[self._selector._main_mode_index] ] #self._selector.mode_index == 1: #if self._selector._sub_mode_index[self._selector._mode_index] > 0: # disable midi map rebuild for instrument mode to prevent light feedback errors if mode != "instrument": new_channel = self._selector.channel_for_current_mode() for note in self._drum_notes: self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) def _send_midi(self, midi_bytes, optimized=None): sent_successfully = False if not self._suppress_send_midi: sent_successfully = ControlSurface._send_midi(self, midi_bytes, optimized=optimized) return sent_successfully def _update_hardware(self): self._suppress_send_midi = False if self._user_byte_write_button != None: self._user_byte_write_button.send_value(1) self._wrote_user_byte = True self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() def _send_challenge(self): # send challenge for all models to allow to detect which one is actually plugged # mk2 challenge_bytes = tuple([ self._challenge >> 8 * index & 127 for index in xrange(4) ]) self._send_midi((240, 0, 32, 41, 2, 24, 64) + challenge_bytes + (247,)) # mk1's for index in range(4): challenge_byte = self._challenge >> 8 * index & 127 self._send_midi((176, 17 + index, challenge_byte)) def _user_byte_value(self, value): assert (value in range(128)) if not self._wrote_user_byte: enabled = (value == 1) self._control_is_with_automap = not enabled self._suppress_send_midi = self._control_is_with_automap if not self._control_is_with_automap: for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.force_next_send() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False else: self._wrote_user_byte = False def _button_value(self, value): assert value in range(128) def _config_value(self, value): assert value in range(128) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if not self._suppress_session_highlight: ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)
class Launchpad(ControlSurface): """ Script for Novation's Launchpad Controller """ def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True 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 = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0) self._config_button.add_value_listener(self._config_value) top_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._selector.name = 'Main_Modes' self._do_combine() for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self._suppress_session_highlight = False self.set_suppress_rebuild_requests(False) self.log_message("LaunchPad85 Loaded !") def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._do_uncombine() self._selector = None self._user_byte_write_button.remove_value_listener( self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None _active_instances = [] def highlighting_session_component(self): " Return the session component showing the ring in Live session " return self._selector.session_component() def _combine_active_instances(): support_devices = False for instance in Launchpad._active_instances: support_devices |= (instance._device_component != None) offset = 0 for instance in Launchpad._active_instances: instance._activate_combination_mode(offset, support_devices) offset += instance._selector._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def _activate_combination_mode(self, track_offset, support_devices): if (LINK_STEPSEQ): self._selector._stepseq.link_with_step_offset(track_offset) if (LINK_SESSION): self._selector._session.link_with_track_offset(track_offset) def _do_combine(self): if (DO_COMBINE and (self not in Launchpad._active_instances)): Launchpad._active_instances.append(self) Launchpad._combine_active_instances() def _do_uncombine(self): if self in Launchpad._active_instances: Launchpad._active_instances.remove(self) if (LINK_SESSION): self._selector._session.unlink() if (LINK_STEPSEQ): self._selector._stepseq.unlink() Launchpad._combine_active_instances() def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): if len(midi_bytes) == 8: if midi_bytes[1:5] == (0, 32, 41, 6): response = long(midi_bytes[5]) response += long(midi_bytes[6]) << 8 if response == Live.Application.encrypt_challenge2( self._challenge): self._suppress_send_midi = False self.set_enabled(True) def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if self._selector.mode_index == 1: new_channel = self._selector.channel_for_current_mode() for note in DRUM_NOTES: self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) def _send_midi(self, midi_bytes): sent_successfully = False if not self._suppress_send_midi: sent_successfully = ControlSurface._send_midi(self, midi_bytes) return sent_successfully def _update_hardware(self): self._suppress_send_midi = False self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() def _send_challenge(self): for index in range(4): challenge_byte = self._challenge >> 8 * index & 127 self._send_midi((176, 17 + index, challenge_byte)) def _user_byte_value(self, value): assert (value in range(128)) if (not self._wrote_user_byte): enabled = (value == 1) self._control_is_with_automap = (not enabled) self._suppress_send_midi = self._control_is_with_automap if not self._control_is_with_automap: for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.set_force_next_value() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False else: self._wrote_user_byte = False def _button_value(self, value): assert (value in range(128)) def _config_value(self, value): assert (value in range(128)) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if not self._suppress_session_highlight: ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)
def __init__(self, c_instance): live = Live.Application.get_application() self._live_major_version = live.get_major_version() self._live_minor_version = live.get_minor_version() self._live_bugfix_version = live.get_bugfix_version() ControlSurface.__init__(self, c_instance) #self._device_selection_follows_track_selection = True with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True 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) # Apparently this CC is used to enable feedback, ie lighting up buttons that you pressed 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 = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (7-row) * 8 + column) # APCmini rows are in reverse order from Launchpad button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0, optimized_send_midi=False) # Control goes through here on LP, no real equivalent in APCmini (I don't think) self._config_button.add_value_listener(self._config_value) top_buttons = [ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 64 + index) for index in range(8)] side_buttons = [ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8)] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._osd = M4LInterface() self._osd.name = "OSD" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self._osd, self) self._selector.name = 'Main_Modes' self._do_combine() for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False self.log_message("LaunchPad95 Loaded !")
class BlockPad(ControlSurface): __module__ = __name__ __doc__ = " Script for Novation's Launchpad Controller adapted to Livid's Block controller and Monomodular by amounra " def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._monomod_version = 'b994' self.hosts = [] self._host_name = 'BlockPad' self._color_type = 'Monochrome' self._timer = 0 is_momentary = True self._suggested_input_port = 'block (Controls)' self._suggested_output_port = 'block (Controls)' self._wrote_user_byte = False matrix = ButtonMatrixElement() for row in range(8): button_row = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((column * 8) + row), 'Button_'+str(column)+'_'+str(row), self) for column in range(8) ] matrix.add_row(tuple(button_row)) knobs = [ EncoderElement(MIDI_CC_TYPE, 0, KNOB_CC[index], Live.MidiMap.MapMode.absolute) for index in range(8) ] sliders = [ EncoderElement(MIDI_CC_TYPE, 0, SLIDER_CC[index], Live.MidiMap.MapMode.absolute) for index in range(2) ] self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0) self._config_button.add_value_listener(self._config_value) top_buttons = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, TOP_NOTES[index], 'Top_Button'+str(index), self) for index in range(8) ] side_buttons = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], 'Side_Button'+str(index), self) for index in range(8) ] self._setup_monobridge() self._setup_monomod() self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, tuple(knobs), tuple(sliders), self) self._user_byte_write_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 16) self._user_byte_value(1) self._user_byte_write_button.add_value_listener(self._user_byte_value) self.set_enabled(True) self.log_message("--------------= BlockPad log opened =--------------") #Create entry in log file self.refresh_state() def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_monomod(self): self._host = MonomodComponent(self) self._host.name = 'Monomod_Host' self.hosts = [self._host] def disconnect(self): self._suppress_send_midi = True self._selector = None self._user_byte_write_button.remove_value_listener(self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None self.log_message("--------------= BlockPad log closed =--------------") #Create entry in log file def _user_byte_value(self, value): assert (value in range(128)) enabled = (value == 1) if enabled: self._config_button.send_value(40) self._control_is_with_automap = (not enabled) for control in self.controls: if isinstance(control, FlashingButtonElement): control.set_force_next_value() if (not self._wrote_user_byte): self._selector.set_mode(0) self.set_enabled(enabled) else: self._wrote_user_byte = False self.request_rebuild_midi_map() def _config_value(self, value): assert (value in range(128)) 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 if(self._timer == 0): self._selector._shift_pressed_timer = -12 self.flash() def flash(self): for row in range(8): for column in range(8): button = self._selector._matrix.get_button(column, row) if(button._flash_state > 0): button.flash(self._timer)
class Launchpad(ControlSurface): """ Script for Novation's Launchpad Controller """ def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True 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 = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) 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_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button) self._selector.name = 'Main_Modes' for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._selector = None self._user_byte_write_button.remove_value_listener(self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): if len(midi_bytes) == 8: if midi_bytes[1:5] == (0, 32, 41, 6): response = long(midi_bytes[5]) response += long(midi_bytes[6]) << 8 if response == Live.Application.encrypt_challenge2(self._challenge): self._on_handshake_successful() def _on_handshake_successful(self): self._suppress_send_midi = False self.set_enabled(True) def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if self._selector.mode_index == 1: new_channel = self._selector.channel_for_current_mode() for note in DRUM_NOTES: self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) def _send_midi(self, midi_bytes, optimized = None): sent_successfully = False if not self._suppress_send_midi: sent_successfully = ControlSurface._send_midi(self, midi_bytes, optimized=optimized) return sent_successfully def _update_hardware(self): self._suppress_send_midi = False self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() def _send_challenge(self): for index in range(4): challenge_byte = self._challenge >> 8 * index & 127 self._send_midi((176, 17 + index, challenge_byte)) def _user_byte_value(self, value): if not value in range(128): raise AssertionError enabled = self._wrote_user_byte or value == 1 self._control_is_with_automap = not enabled self._suppress_send_midi = self._control_is_with_automap if not self._control_is_with_automap: for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.set_force_next_value() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False else: self._wrote_user_byte = False def _button_value(self, value): raise value in range(128) or AssertionError def _config_value(self, value): raise value in range(128) or AssertionError def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if not self._suppress_session_highlight: ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)
class Launchpad(ControlSurface): " Script for Novation's Launchpad Controller " def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True 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 = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column)) button.name = (((str(column) + "_Clip_") + str(row)) + "_Button") button_row.append(button) matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0) self._config_button.add_value_listener(self._config_value) top_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, (104 + index)) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = "Bank_Select_Up_Button" top_buttons[1].name = "Bank_Select_Down_Button" top_buttons[2].name = "Bank_Select_Left_Button" top_buttons[3].name = "Bank_Select_Right_Button" top_buttons[4].name = "Session_Button" top_buttons[5].name = "User1_Button" top_buttons[6].name = "User2_Button" top_buttons[7].name = "Mixer_Button" side_buttons[0].name = "Vol_Button" side_buttons[1].name = "Pan_Button" side_buttons[2].name = "SndA_Button" side_buttons[3].name = "SndB_Button" side_buttons[4].name = "Stop_Button" side_buttons[5].name = "Trk_On_Button" side_buttons[6].name = "Solo_Button" side_buttons[7].name = "Arm_Button" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._selector.name = "Main_Modes" for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self._suppress_session_highlight = False self.set_suppress_rebuild_requests(False) self.log_message("LaunchPad85 Loaded !") def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._selector = None self._user_byte_write_button.remove_value_listener(self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None def highlighting_session_component(self): " Return the session component showing the ring in Live session " return self._selector.session_component() def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): if (len(midi_bytes) == 8): if (midi_bytes[1:5] == (0, 32, 41, 6)): response = long(midi_bytes[5]) response += (long(midi_bytes[6]) << 8) if (response == Live.Application.encrypt_challenge2(self._challenge)): self._suppress_send_midi = False self.set_enabled(True) def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if (self._selector.mode_index == 1): new_channel = self._selector.channel_for_current_mode() for note in DRUM_NOTES: self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) def _send_midi(self, midi_bytes): sent_successfully = False if (not self._suppress_send_midi): sent_successfully = ControlSurface._send_midi(self, midi_bytes) return sent_successfully def _update_hardware(self): self._suppress_send_midi = False self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() def _send_challenge(self): for index in range(4): challenge_byte = ((self._challenge >> (8 * index)) & 127) self._send_midi((176, (17 + index), challenge_byte)) def _user_byte_value(self, value): assert (value in range(128)) if (not self._wrote_user_byte): enabled = (value == 1) self._control_is_with_automap = (not enabled) self._suppress_send_midi = self._control_is_with_automap if (not self._control_is_with_automap): for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.set_force_next_value() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False else: self._wrote_user_byte = False def _button_value(self, value): assert (value in range(128)) def _config_value(self, value): assert (value in range(128)) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if (not self._suppress_session_highlight): ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)
class Launchpad(ControlSurface): """ Script for Novation's Launchpad Controller """ def __init__(self, c_instance): live = Live.Application.get_application() self._live_major_version = live.get_major_version() self._live_minor_version = live.get_minor_version() self._live_bugfix_version = live.get_bugfix_version() self._mk2 = Settings.DEVICE == 'Launchpad mk2' if self._mk2: self._skin = Skin('Launchpad mk2') self._side_notes = (89, 79, 69, 59, 49, 39, 29, 19) self._drum_notes = (20, 30, 31, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126) else: self._skin = Skin('Launchpad') self._side_notes = (8, 24, 40, 56, 72, 88, 104, 120) self._drum_notes = (41, 42, 43, 44, 45, 46, 47, 57, 58, 59, 60, 61, 62, 63, 73, 74, 75, 76, 77, 78, 79, 89, 90, 91, 92, 93, 94, 95, 105, 106, 107) ControlSurface.__init__(self, c_instance) with self.component_guard(): self._suppress_send_midi = True self._suppress_session_highlight = True is_momentary = True if self._mk2: self._suggested_input_port = 'Launchpad' self._suggested_output_port = 'Launchpad' else: self._suggested_input_port = 'Launchpad MK2' self._suggested_output_port = 'Launchpad MK2' 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 = [] for column in range(8): if self._mk2: # for mk2 buttons are assigned "top to bottom" midi_note = (81 - (10 * row)) + column else: midi_note = row * 16 + column button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, midi_note, self._skin.off) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) 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_buttons = [ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index, self._skin.off) for index in range(8)] side_buttons = [ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, self._side_notes[index], self._skin.off) for index in range(8)] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._osd = M4LInterface() self._osd.name = "OSD" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self._osd, self, self._skin) self._selector.name = 'Main_Modes' self._do_combine() for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False self.log_message("LaunchPad95 Loaded !") def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._do_uncombine() self._selector = None self._user_byte_write_button.remove_value_listener(self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False if self._mk2: self._send_midi((240, 0, 32, 41, 2, 24, 64, 247)) # launchpad mk2 needs disconnect string sent self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None _active_instances = [] #def highlighting_session_component(self): # " Return the session component showing the ring in Live session " # return self._selector.session_component() def _combine_active_instances(): support_devices = False for instance in Launchpad._active_instances: support_devices |= (instance._device_component != None) offset = 0 for instance in Launchpad._active_instances: instance._activate_combination_mode(offset, support_devices) offset += instance._selector._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def _activate_combination_mode(self, track_offset, support_devices): if(Settings.STEPSEQ__LINK_WITH_SESSION): self._selector._stepseq.link_with_step_offset(track_offset) if(Settings.SESSION__LINK): self._selector._session.link_with_track_offset(track_offset) def _do_combine(self): if (DO_COMBINE and (self not in Launchpad._active_instances)): Launchpad._active_instances.append(self) Launchpad._combine_active_instances() def _do_uncombine(self): if self in Launchpad._active_instances: Launchpad._active_instances.remove(self) if(Settings.SESSION__LINK): self._selector._session.unlink() if(Settings.STEPSEQ__LINK_WITH_SESSION): self._selector._stepseq.unlink() Launchpad._combine_active_instances() def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): if self._mk2: # mk2 has different challenge and params if len(midi_bytes) == 10: if midi_bytes[:7] == (240, 0, 32, 41, 2, 24, 64): response = long(midi_bytes[7]) response += long(midi_bytes[8]) << 8 if response == Live.Application.encrypt_challenge2(self._challenge): # self.log_message("Challenge Response ok") self._suppress_send_midi = False self.set_enabled(True) else: if len(midi_bytes) == 8: if midi_bytes[1:5] == (0, 32, 41, 6): response = long(midi_bytes[5]) response += long(midi_bytes[6]) << 8 if response == Live.Application.encrypt_challenge2(self._challenge): self._suppress_send_midi = False self.set_enabled(True) def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if self._selector.mode_index == 1: if self._selector._sub_mode_index[self._selector._mode_index] > 0: # disable midi map rebuild for instrument mode to prevent light feedback errors new_channel = self._selector.channel_for_current_mode() # self.log_message(str(new_channel)) for note in self.drum_notes: self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) def _send_midi(self, midi_bytes, optimized=None): sent_successfully = False if not self._suppress_send_midi: sent_successfully = ControlSurface._send_midi(self, midi_bytes, optimized=optimized) return sent_successfully def _update_hardware(self): self._suppress_send_midi = False self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() def _send_challenge(self): if self._mk2: challenge_bytes = tuple([ self._challenge >> 8 * index & 127 for index in xrange(4) ]) self._send_midi((240, 0, 32, 41, 2, 24, 64) + challenge_bytes + (247,)) else: for index in range(4): challenge_byte = self._challenge >> 8 * index & 127 self._send_midi((176, 17 + index, challenge_byte)) def _user_byte_value(self, value): assert (value in range(128)) if not self._wrote_user_byte: enabled = (value == 1) self._control_is_with_automap = not enabled self._suppress_send_midi = self._control_is_with_automap if not self._control_is_with_automap: for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.set_force_next_value() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False else: self._wrote_user_byte = False def _button_value(self, value): assert value in range(128) def _config_value(self, value): assert value in range(128) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if not self._suppress_session_highlight: ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)
class LaunchMod(ControlSurface): __module__ = __name__ __doc__ = " Script for Novation's Launchpad Controller " def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._monomod_version = 'b994' self._host_name = 'LaunchMod' self._color_type = 'Launchpad' self.hosts = [] self._timer = 0 self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True is_momentary = True self._suggested_input_port = 'Launchpad' self._suggested_output_port = 'Launchpad' self._wrote_user_byte = False self._control_is_with_automap = False self._challenge = (Live.Application.get_random_int(0, 400000000) & 2139062143) matrix = ButtonMatrixElement() matrix.name = 'ButtonMatrix' for row in range(8): #button_row = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column)) for column in range(8) ] button_row = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column), 'Button_' + str(row) + '_' + str(column), self) for column in range(8) ] matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0) self._config_button.add_value_listener(self._config_value) top_buttons = [ FlashingButtonElement(is_momentary, MIDI_CC_TYPE, 0, (104 + index), 'Top_Button' + str(index), self) for index in range(8) ] side_buttons = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], 'Side_Button' + str(index), self) for index in range(8) ] self._setup_monobridge() self._setup_monomod() self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._suppress_session_highlight = False self._suppress_send_midi = False self._user_byte_write_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 16) self._user_byte_write_button.send_value(1) self._user_byte_write_button.add_value_listener(self._user_byte_value) self._suppress_send_midi = True self.set_suppress_rebuild_requests(False) self.log_message("--------------= LaunchMod log opened =--------------" ) #Create entry in log file self.refresh_state() def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_monomod(self): self._host = MonomodComponent(self) self._host.name = 'Monomod_Host' self.hosts = [self._host] def disconnect(self): self._suppress_send_midi = True self._selector = None self._user_byte_write_button.remove_value_listener( self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None self.log_message("--------------= LaunchMod log closed =--------------" ) #Create entry in log file def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): if (len(midi_bytes) == 8): if (midi_bytes[1:5] == (0, 32, 41, 6)): response = long(midi_bytes[5]) response += (long(midi_bytes[6]) << 8) if (response == Live.Application.encrypt_challenge2( self._challenge)): self._suppress_send_midi = False self.set_enabled(True) #self.refresh_state() def _send_midi(self, midi_bytes): if (not self._suppress_send_midi): ControlSurface._send_midi(self, midi_bytes) def _update_hardware(self): self._suppress_send_midi = False self._config_button.send_value(40) self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() def _send_challenge(self): for index in range(4): challenge_byte = ((self._challenge >> (8 * index)) & 127) self._send_midi((176, (17 + index), challenge_byte)) def _user_byte_value(self, value): assert (value in range(128)) enabled = (value == 1) if enabled: self._config_button.send_value(40) self._control_is_with_automap = (not enabled) for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.set_force_next_value() if (not self._wrote_user_byte): self._selector.set_mode(0) self.set_enabled(enabled) else: self._wrote_user_byte = False self.request_rebuild_midi_map() def _config_value(self, value): assert (value in range(128)) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_returns=False): if (not self._suppress_session_highlight): ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_returns) def _install_forwarding(self, control): result = False if ((not self._control_is_with_automap) or (control == self._user_byte_write_button)): result = ControlSurface._install_forwarding(self, control) return result def _translate_message(self, type, from_identifier, from_channel, to_identifier, to_channel): if (not self._control_is_with_automap): ControlSurface._translate_message(self, type, from_identifier, from_channel, to_identifier, to_channel) 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() def flash(self): #if(self.flash_status > 0): for row in range(8): if (self._selector._side_buttons[row]._flash_state > 0): self._selector._side_buttons[row].flash(self._timer) for column in range(8): button = self._selector._matrix.get_button(column, row) if (button._flash_state > 0): button.flash(self._timer) for index in range(4): if (self._selector._nav_buttons[index]._flash_state > 0): self._selector._nav_buttons[index].flash(self._timer) if (self._selector._modes_buttons[index]._flash_state > 0): self._selector._modes_buttons[index].flash(self._timer) def allow_updates(self, allow_updates): for component in self.components: component.set_allow_update(int(allow_updates != 0))
class Launchpad(ControlSurface): """ Script for Novation's Launchpad Controller """ def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True 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 = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0) self._config_button.add_value_listener(self._config_value) top_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._selector.name = 'Main_Modes' self._do_combine() for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self._suppress_session_highlight = False self.set_suppress_rebuild_requests(False) self.log_message("LaunchPad85 Loaded !") def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._do_uncombine() self._selector = None self._user_byte_write_button.remove_value_listener(self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None _active_instances = [] def highlighting_session_component(self): " Return the session component showing the ring in Live session " return self._selector.session_component() def _combine_active_instances(): support_devices = False for instance in Launchpad._active_instances: support_devices |= (instance._device_component != None) offset = 0 for instance in Launchpad._active_instances: instance._activate_combination_mode(offset, support_devices) offset += instance._selector._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def _activate_combination_mode(self, track_offset, support_devices): if(LINK_STEPSEQ): self._selector._stepseq.link_with_step_offset(track_offset) if(LINK_SESSION): self._selector._session.link_with_track_offset(track_offset) def _do_combine(self): if (DO_COMBINE and (self not in Launchpad._active_instances)): Launchpad._active_instances.append(self) Launchpad._combine_active_instances() def _do_uncombine(self): if self in Launchpad._active_instances: Launchpad._active_instances.remove(self) if(LINK_SESSION): self._selector._session.unlink() if(LINK_STEPSEQ): self._selector._stepseq.unlink() Launchpad._combine_active_instances() def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): if len(midi_bytes) == 8: if midi_bytes[1:5] == (0, 32, 41, 6): response = long(midi_bytes[5]) response += long(midi_bytes[6]) << 8 if response == Live.Application.encrypt_challenge2(self._challenge): self._suppress_send_midi = False self.set_enabled(True) def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if self._selector.mode_index == 1: new_channel = self._selector.channel_for_current_mode() for note in DRUM_NOTES: self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) def _send_midi(self, midi_bytes): sent_successfully = False if not self._suppress_send_midi: sent_successfully = ControlSurface._send_midi(self, midi_bytes) return sent_successfully def _update_hardware(self): self._suppress_send_midi = False self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() def _send_challenge(self): for index in range(4): challenge_byte = self._challenge >> 8 * index & 127 self._send_midi((176, 17 + index, challenge_byte)) def _user_byte_value(self, value): assert (value in range(128)) if (not self._wrote_user_byte): enabled = (value == 1) self._control_is_with_automap = (not enabled) self._suppress_send_midi = self._control_is_with_automap if not self._control_is_with_automap: for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.set_force_next_value() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False else: self._wrote_user_byte = False def _button_value(self, value): assert (value in range(128)) def _config_value(self, value): assert (value in range(128)) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if not self._suppress_session_highlight: ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)
class LaunchMod(ControlSurface): __module__ = __name__ __doc__ = " Script for Novation's Launchpad Controller " def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._monomod_version = 'b994' self._host_name = 'LaunchMod' self._color_type = 'Launchpad' self.hosts = [] self._timer = 0 self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True is_momentary = True self._suggested_input_port = 'Launchpad' self._suggested_output_port = 'Launchpad' self._wrote_user_byte = False self._control_is_with_automap = False self._challenge = (Live.Application.get_random_int(0, 400000000) & 2139062143) matrix = ButtonMatrixElement() matrix.name = 'ButtonMatrix' for row in range(8): #button_row = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column)) for column in range(8) ] button_row = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column), 'Button_'+str(row)+'_'+str(column), self) for column in range(8) ] matrix.add_row(tuple(button_row)) self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0) self._config_button.add_value_listener(self._config_value) top_buttons = [ FlashingButtonElement(is_momentary, MIDI_CC_TYPE, 0, (104 + index), 'Top_Button'+str(index), self) for index in range(8) ] side_buttons = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], 'Side_Button'+str(index), self) for index in range(8) ] self._setup_monobridge() self._setup_monomod() self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self) self._suppress_session_highlight = False self._suppress_send_midi = False self._user_byte_write_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 16) self._user_byte_write_button.send_value(1) self._user_byte_write_button.add_value_listener(self._user_byte_value) self._suppress_send_midi = True self.set_suppress_rebuild_requests(False) self.log_message("--------------= LaunchMod log opened =--------------") #Create entry in log file self.refresh_state() def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_monomod(self): self._host = MonomodComponent(self) self._host.name = 'Monomod_Host' self.hosts = [self._host] def disconnect(self): self._suppress_send_midi = True self._selector = None self._user_byte_write_button.remove_value_listener(self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None self.log_message("--------------= LaunchMod log closed =--------------") #Create entry in log file def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) def handle_sysex(self, midi_bytes): if (len(midi_bytes) == 8): if (midi_bytes[1:5] == (0, 32, 41, 6)): response = long(midi_bytes[5]) response += (long(midi_bytes[6]) << 8) if (response == Live.Application.encrypt_challenge2(self._challenge)): self._suppress_send_midi = False self.set_enabled(True) #self.refresh_state() def _send_midi(self, midi_bytes): if (not self._suppress_send_midi): ControlSurface._send_midi(self, midi_bytes) def _update_hardware(self): self._suppress_send_midi = False self._config_button.send_value(40) self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() def _send_challenge(self): for index in range(4): challenge_byte = ((self._challenge >> (8 * index)) & 127) self._send_midi((176, (17 + index), challenge_byte)) def _user_byte_value(self, value): assert (value in range(128)) enabled = (value == 1) if enabled: self._config_button.send_value(40) self._control_is_with_automap = (not enabled) for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.set_force_next_value() if (not self._wrote_user_byte): self._selector.set_mode(0) self.set_enabled(enabled) else: self._wrote_user_byte = False self.request_rebuild_midi_map() def _config_value(self, value): assert (value in range(128)) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_returns = False): if (not self._suppress_session_highlight): ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_returns) def _install_forwarding(self, control): result = False if ((not self._control_is_with_automap) or (control == self._user_byte_write_button)): result = ControlSurface._install_forwarding(self, control) return result def _translate_message(self, type, from_identifier, from_channel, to_identifier, to_channel): if (not self._control_is_with_automap): ControlSurface._translate_message(self, type, from_identifier, from_channel, to_identifier, to_channel) 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() def flash(self): #if(self.flash_status > 0): for row in range(8): if(self._selector._side_buttons[row]._flash_state > 0): self._selector._side_buttons[row].flash(self._timer) for column in range(8): button = self._selector._matrix.get_button(column, row) if(button._flash_state > 0): button.flash(self._timer) for index in range(4): if(self._selector._nav_buttons[index]._flash_state > 0): self._selector._nav_buttons[index].flash(self._timer) if(self._selector._modes_buttons[index]._flash_state > 0): self._selector._modes_buttons[index].flash(self._timer) def allow_updates(self, allow_updates): for component in self.components: component.set_allow_update(int(allow_updates!=0))
def init(self): #skip init if already done. if self._init_done: return self._init_done = True # second part of the __init__ after model has been identified using its challenge response if self._mk2_rgb: from SkinMK2 import make_skin self._skin = make_skin() self._side_notes = (89, 79, 69, 59, 49, 39, 29, 19) #self._drum_notes = (20, 30, 31, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126) self._drum_notes = (20, 30, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126) else: from SkinMK1 import make_skin self._skin = make_skin() self._side_notes = (8, 24, 40, 56, 72, 88, 104, 120) self._drum_notes = (41, 42, 43, 44, 45, 46, 47, 57, 58, 59, 60, 61, 62, 63, 73, 74, 75, 76, 77, 78, 79, 89, 90, 91, 92, 93, 94, 95, 105, 106, 107) with self.component_guard(): is_momentary = True self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0, optimized_send_midi=False) self._config_button.add_value_listener(self._config_value) self._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) matrix = ButtonMatrixElement() matrix.name = 'Button_Matrix' for row in range(8): button_row = [] for column in range(8): if self._mk2_rgb: # for mk2 buttons are assigned "top to bottom" midi_note = (81 - (10 * row)) + column else: midi_note = row * 16 + column button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, midi_note, skin = self._skin, control_surface = self) button.name = str(column) + '_Clip_' + str(row) + '_Button' button_row.append(button) matrix.add_row(tuple(button_row)) top_buttons = [ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index, skin = self._skin) for index in range(8)] side_buttons = [ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, self._side_notes[index], skin = self._skin) for index in range(8)] top_buttons[0].name = 'Bank_Select_Up_Button' top_buttons[1].name = 'Bank_Select_Down_Button' top_buttons[2].name = 'Bank_Select_Left_Button' top_buttons[3].name = 'Bank_Select_Right_Button' top_buttons[4].name = 'Session_Button' top_buttons[5].name = 'User1_Button' top_buttons[6].name = 'User2_Button' top_buttons[7].name = 'Mixer_Button' side_buttons[0].name = 'Vol_Button' side_buttons[1].name = 'Pan_Button' side_buttons[2].name = 'SndA_Button' side_buttons[3].name = 'SndB_Button' side_buttons[4].name = 'Stop_Button' side_buttons[5].name = 'Trk_On_Button' side_buttons[6].name = 'Solo_Button' side_buttons[7].name = 'Arm_Button' self._osd = M4LInterface() self._osd.name = "OSD" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button, self._osd, self) self._selector.name = 'Main_Modes' self._do_combine() for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False # due to our 2 stage init, we need to rebuild midi map self.request_rebuild_midi_map() # and request update self._selector.update() if self._mk2_rgb: self.log_message("LaunchPad95 (mk2) Loaded !") else: self.log_message("LaunchPad95 Loaded !")
class Launchpad(ControlSurface): " SCRIPT FOR NOVATION'S LAUNCHPAD CONTROLLER " " INITALIZE " def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): #self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True 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" """ TRACKFINDER TEST track_index = 0 for track in self.song().tracks: if track_index < 8: button_row = [] if track.is_foldable: for column in range(8): log("right one: " + str(track_index)) button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((track_index * 16) + column)) #@UndefinedVariable button.name = (((str(column) + "_Clip_") + str(track_index)) + "_Button") button_row.append(button) track_index = track_index + 1 else: for column in range(8): log("wrong one: " + str(track_index)) button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99, True) #@UndefinedVariable button.name = (str(column) + "_Clip_Button-DUMMY") button_row.append(button) matrix.add_row(tuple(button_row)) log("done")""" """ ORIGINAL CODE """ for row in range(8): button_row = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column)) button.name = (((str(column) + "_Clip_") + str(row)) + "_Button") button_row.append(button) 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_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, (104 + index)) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = "Bank_Select_Up_Button" top_buttons[1].name = "Bank_Select_Down_Button" top_buttons[2].name = "Bank_Select_Left_Button" top_buttons[3].name = "Bank_Select_Right_Button" top_buttons[4].name = "Session_Button" top_buttons[5].name = "User1_Button" top_buttons[6].name = "User2_Button" top_buttons[7].name = "Mixer_Button" side_buttons[0].name = "Vol_Button" side_buttons[1].name = "Pan_Button" side_buttons[2].name = "SndA_Button" side_buttons[3].name = "SndB_Button" side_buttons[4].name = "Stop_Button" side_buttons[5].name = "Trk_On_Button" side_buttons[6].name = "Solo_Button" side_buttons[7].name = "Arm_Button" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button) self._selector.name = "Main_Modes" for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component( self._selector.session_component()) self._suppress_session_highlight = False #self.set_suppress_rebuild_requests(False) " DISCONNECTOR " def disconnect(self): self._suppress_send_midi = True for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.remove_value_listener(self._button_value) self._selector = None self._user_byte_write_button.remove_value_listener( self._user_byte_value) self._config_button.remove_value_listener(self._config_value) ControlSurface.disconnect(self) self._suppress_send_midi = False self._config_button.send_value(32) self._config_button.send_value(0) self._config_button = None self._user_byte_write_button.send_value(0) self._user_byte_write_button = None " RETURN THE SESSION COMPONENT SHOWING THE RING IN LIVE SESSION " def highlighting_session_component(self): return self._selector.session_component() " REFRESH " def refresh_state(self): ControlSurface.refresh_state(self) self.schedule_message(5, self._update_hardware) " SYSEX HANDLING " def handle_sysex(self, midi_bytes): if (len(midi_bytes) == 8): if (midi_bytes[1:5] == (0, 32, 41, 6)): response = long(midi_bytes[5]) response += (long(midi_bytes[6]) << 8) if (response == Live.Application.encrypt_challenge2( self._challenge)): self._suppress_send_midi = False self.set_enabled(True) " MIDI MAP " def build_midi_map(self, midi_map_handle): ControlSurface.build_midi_map(self, midi_map_handle) if (self._selector.mode_index == 1): new_channel = self._selector.channel_for_current_mode() for note in DRUM_NOTES: self._translate_message(MIDI_NOTE_TYPE, note, 0, note, new_channel) " SEND THE MIDI STUFF " def _send_midi(self, midi_bytes, optimized=None): sent_successfully = False if (not self._suppress_send_midi): sent_successfully = ControlSurface._send_midi(self, midi_bytes, optimized=optimized) return sent_successfully " UPDATE THE HARDWARE " def _update_hardware(self): self._suppress_send_midi = False self._wrote_user_byte = True self._user_byte_write_button.send_value(1) self._suppress_send_midi = True self.set_enabled(False) self._suppress_send_midi = False self._send_challenge() " CHALLANGE SEND " def _send_challenge(self): for index in range(4): challenge_byte = ((self._challenge >> (8 * index)) & 127) self._send_midi((176, (17 + index), challenge_byte)) " USER BYTE STUFF " def _user_byte_value(self, value): if not value in range(128): raise AssertionError enabled = self._wrote_user_byte or value == 1 self._control_is_with_automap = not enabled self._suppress_send_midi = self._control_is_with_automap if not self._control_is_with_automap: for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.set_force_next_value() self._selector.set_mode(0) self.set_enabled(enabled) self._suppress_send_midi = False else: self._wrote_user_byte = False " BUTTON VALUE " def _button_value(self, value): assert (value in range(128)) " CONFIG VALUE " def _config_value(self, value): assert (value in range(128)) " SET THE SESSION HIGHLIGHT " def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): if (not self._suppress_session_highlight): ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): #self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True 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" """ TRACKFINDER TEST track_index = 0 for track in self.song().tracks: if track_index < 8: button_row = [] if track.is_foldable: for column in range(8): log("right one: " + str(track_index)) button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((track_index * 16) + column)) #@UndefinedVariable button.name = (((str(column) + "_Clip_") + str(track_index)) + "_Button") button_row.append(button) track_index = track_index + 1 else: for column in range(8): log("wrong one: " + str(track_index)) button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99, True) #@UndefinedVariable button.name = (str(column) + "_Clip_Button-DUMMY") button_row.append(button) matrix.add_row(tuple(button_row)) log("done")""" """ ORIGINAL CODE """ for row in range(8): button_row = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column)) button.name = (((str(column) + "_Clip_") + str(row)) + "_Button") button_row.append(button) 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_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, (104 + index)) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = "Bank_Select_Up_Button" top_buttons[1].name = "Bank_Select_Down_Button" top_buttons[2].name = "Bank_Select_Left_Button" top_buttons[3].name = "Bank_Select_Right_Button" top_buttons[4].name = "Session_Button" top_buttons[5].name = "User1_Button" top_buttons[6].name = "User2_Button" top_buttons[7].name = "Mixer_Button" side_buttons[0].name = "Vol_Button" side_buttons[1].name = "Pan_Button" side_buttons[2].name = "SndA_Button" side_buttons[3].name = "SndB_Button" side_buttons[4].name = "Stop_Button" side_buttons[5].name = "Trk_On_Button" side_buttons[6].name = "Solo_Button" side_buttons[7].name = "Arm_Button" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button) self._selector.name = "Main_Modes" for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component(self._selector.session_component()) self._suppress_session_highlight = False
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): #self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True 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" """ TRACKFINDER TEST track_index = 0 for track in self.song().tracks: if track_index < 8: button_row = [] if track.is_foldable: for column in range(8): log("right one: " + str(track_index)) button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((track_index * 16) + column)) #@UndefinedVariable button.name = (((str(column) + "_Clip_") + str(track_index)) + "_Button") button_row.append(button) track_index = track_index + 1 else: for column in range(8): log("wrong one: " + str(track_index)) button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99, True) #@UndefinedVariable button.name = (str(column) + "_Clip_Button-DUMMY") button_row.append(button) matrix.add_row(tuple(button_row)) log("done")""" """ ORIGINAL CODE """ for row in range(8): button_row = [] for column in range(8): button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, ((row * 16) + column)) button.name = (((str(column) + "_Clip_") + str(row)) + "_Button") button_row.append(button) 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_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, (104 + index)) for index in range(8) ] side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index]) for index in range(8) ] top_buttons[0].name = "Bank_Select_Up_Button" top_buttons[1].name = "Bank_Select_Down_Button" top_buttons[2].name = "Bank_Select_Left_Button" top_buttons[3].name = "Bank_Select_Right_Button" top_buttons[4].name = "Session_Button" top_buttons[5].name = "User1_Button" top_buttons[6].name = "User2_Button" top_buttons[7].name = "Mixer_Button" side_buttons[0].name = "Vol_Button" side_buttons[1].name = "Pan_Button" side_buttons[2].name = "SndA_Button" side_buttons[3].name = "SndB_Button" side_buttons[4].name = "Stop_Button" side_buttons[5].name = "Trk_On_Button" side_buttons[6].name = "Solo_Button" side_buttons[7].name = "Arm_Button" self._selector = MainSelectorComponent(matrix, tuple(top_buttons), tuple(side_buttons), self._config_button) self._selector.name = "Main_Modes" for control in self.controls: if isinstance(control, ConfigurableButtonElement): control.add_value_listener(self._button_value) self.set_highlighting_session_component( self._selector.session_component()) self._suppress_session_highlight = False