class DS1(ControlSurface): __module__ = __name__ __doc__ = " DS1 controller script " def __init__(self, c_instance): super(DS1, self).__init__(c_instance) self._connected = False self._host_name = "DS1" self.oscServer = None self._rgb = 0 self._timer = 0 self.flash_status = 1 self._touched = 0 self._update_linked_device_selection = None self._skin = Skin(DS1Colors) with self.component_guard(): self._setup_monobridge() self._setup_controls() self._setup_m4l_interface() self._define_sysex() self._initialize_hardware() self._setup_mixer_control() self._setup_session_control() self._setup_transport_control() self._setup_device_control() self._setup_session_recording_component() # self._setup_translations() self._setup_main_modes() # self._device.add_device_listener(self._on_new_device_set) self.log_message("<<<<<<<<<<<<<<<<<= DS1 log opened =>>>>>>>>>>>>>>>>>>>>>") # self.schedule_message(3, self._initialize_hardware) """script initialization methods""" def _initialize_hardware(self): self.local_control_off.enter_mode() self.encoder_absolute_mode.enter_mode() self.encoder_speed_sysex.enter_mode() def _check_connection(self): if not self._connected: self._send_midi(QUERYSURFACE) self.schedule_message(100, self._check_connection) def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = "MonoBridge" def _setup_controls(self): is_momentary = True self._fader = [ MonoEncoderElement( MIDI_CC_TYPE, CHANNEL, DS1_FADERS[index], Live.MidiMap.MapMode.absolute, "Fader_" + str(index), index, self, ) for index in range(8) ] for fader in self._fader: fader._mapping_feedback_delay = -1 self._dial = [ [ MonoEncoderElement( MIDI_CC_TYPE, CHANNEL, DS1_DIALS[x][y], Live.MidiMap.MapMode.absolute, "Dial_" + str(x) + "_" + str(y), x + (y * 5), self, ) for x in range(8) ] for y in range(5) ] for row in self._dial: for dial in row: dial._mapping_feedback_delay = -1 self._side_dial = [ MonoEncoderElement( MIDI_CC_TYPE, CHANNEL, DS1_SIDE_DIALS[x], Live.MidiMap.MapMode.absolute, "Side_Dial_" + str(x), x, self ) for x in range(4) ] for dial in self._side_dial: dial._mapping_feedback_delay = -1 self._encoder = [ MonoEncoderElement( MIDI_CC_TYPE, CHANNEL, DS1_ENCODERS[x], Live.MidiMap.MapMode.absolute, "Encoder_" + str(x), x, self ) for x in range(4) ] for encoder in self._encoder: encoder._mapping_feedback_delay = -1 self._encoder_button = [ MonoButtonElement( is_momentary, MIDI_NOTE_TYPE, CHANNEL, DS1_ENCODER_BUTTONS[index], "EncoderButton_" + str(index), self, skin=self._skin, ) for index in range(4) ] self._master_fader = MonoEncoderElement( MIDI_CC_TYPE, CHANNEL, DS1_MASTER, Live.MidiMap.MapMode.absolute, "MasterFader", 0, self ) self._button = [ MonoButtonElement( is_momentary, MIDI_NOTE_TYPE, CHANNEL, DS1_BUTTONS[index], "Button_" + str(index), self, skin=self._skin ) for index in range(16) ] self._grid = [ [ MonoButtonElement( is_momentary, MIDI_NOTE_TYPE, CHANNEL, DS1_GRID[x][y], "Button_" + str(x) + "_" + str(y), self, skin=self._skin, ) for x in range(3) ] for y in range(3) ] self._dummy = [ MonoEncoderElement( MIDI_CC_TYPE, CHANNEL, 120 + x, Live.MidiMap.MapMode.absolute, "Dummy_Dial_" + str(x), x, self ) for x in range(5) ] self._fader_matrix = ButtonMatrixElement(name="FaderMatrix", rows=[self._fader]) self._top_buttons = ButtonMatrixElement(name="TopButtonMatrix", rows=[self._button[:8]]) self._bottom_buttons = ButtonMatrixElement(name="BottomButtonMatrix", rows=[self._button[8:]]) self._dial_matrix = ButtonMatrixElement(name="DialMatrix", rows=self._dial) self._side_dial_matrix = ButtonMatrixElement(name="SideDialMatrix", rows=[self._side_dial]) self._encoder_matrix = ButtonMatrixElement(name="EncoderMatrix", rows=[self._encoder]) self._encoder_button_matrix = ButtonMatrixElement(name="EncoderButtonMatrix", rows=[self._encoder_button]) self._grid_matrix = ButtonMatrixElement(name="GridMatrix", rows=self._grid) self._selected_parameter_controls = ButtonMatrixElement( name="SelectedParameterControls", rows=[self._dummy + self._encoder[:1] + self._encoder[2:]] ) def _define_sysex(self): self._livid_settings = LividSettings(model=16, control_surface=self) self.encoder_speed_sysex = SendLividSysexMode( livid_settings=self._livid_settings, call="set_encoder_mapping", message=ENCODER_SPEED ) self.encoder_absolute_mode = SendLividSysexMode( livid_settings=self._livid_settings, call="set_encoder_encosion_mode", message=[2] ) self.local_control_off = SendLividSysexMode( livid_settings=self._livid_settings, call="set_local_control", message=[0] ) self.main_mode_message = DisplayMessageMode(self, "Mute/Solo Mode") self.select_mode_message = DisplayMessageMode(self, "Arm/Select Mode") self.clip_mode_message = DisplayMessageMode(self, "Launch/Stop Mode") def _setup_autoarm(self): self._auto_arm = AutoArmComponent(name="Auto_Arm") self._auto_arm.can_auto_arm_track = self._can_auto_arm_track def _setup_mixer_control(self): self._num_tracks = 8 self._mixer = MixerComponent(num_tracks=8, num_returns=4, invert_mute_feedback=True, auto_name=True) self._mixer.name = "Mixer" self._mixer.set_track_offset(0) self._mixer.master_strip().set_volume_control(self._master_fader) self._mixer.set_prehear_volume_control(self._side_dial[3]) self._mixer.layer = Layer(volume_controls=self._fader_matrix, track_select_dial=self._encoder[1]) self._strip = [self._mixer.channel_strip(index) for index in range(8)] for index in range(8): self._strip[index].layer = Layer(parameter_controls=self._dial_matrix.submatrix[index : index + 1, :]) self._mixer.selected_strip().layer = Layer(parameter_controls=self._selected_parameter_controls) self._mixer.master_strip().layer = Layer(parameter_controls=self._side_dial_matrix.submatrix[:3, :]) self._mixer.main_layer = AddLayerMode( self._mixer, Layer(solo_buttons=self._bottom_buttons, mute_buttons=self._top_buttons) ) self._mixer.select_layer = AddLayerMode( self._mixer, Layer(arm_buttons=self._bottom_buttons, track_select_buttons=self._top_buttons) ) self.song().view.selected_track = self._mixer.channel_strip(0)._track self._mixer.set_enabled(True) def _setup_session_control(self): self._session = DS1SessionComponent(num_tracks=8, num_scenes=1, auto_name=True, enable_skinning=True) self._session.set_offsets(0, 0) self._session.set_mixer(self._mixer) self._session.layer = Layer( track_select_dial=ComboElement(self._encoder[1], modifiers=[self._encoder_button[1]]), scene_bank_up_button=self._grid[0][1], scene_bank_down_button=self._grid[0][2], scene_launch_buttons=self._grid_matrix.submatrix[1:2, 1:2], ) self._session.clips_layer = AddLayerMode( self._session, Layer(clip_launch_buttons=self._top_buttons, stop_track_clip_buttons=self._bottom_buttons) ) self.set_highlighting_session_component(self._session) self._session._do_show_highlight() def _setup_transport_control(self): self._transport = DS1TransportComponent() self._transport.name = "Transport" self._transport.layer = Layer( stop_button=self._grid[1][0], play_button=self._grid[0][0], record_button=self._grid[2][0] ) self._transport.set_enabled(True) def _setup_device_control(self): self._device = DeviceComponent() self._device.name = "Device_Component" self.set_device_component(self._device) self._device_navigator = DeviceNavigator(self._device, self._mixer, self) self._device_navigator.name = "Device_Navigator" # self._device_selection_follows_track_selection = FOLLOW self._device.device_name_data_source().set_update_callback(self._on_device_name_changed) def _setup_session_recording_component(self): self._clip_creator = ClipCreator() self._clip_creator.name = "ClipCreator" self._recorder = SessionRecordingComponent(self._clip_creator, ViewControlComponent()) self._recorder.set_enabled(True) self._recorder.layer = Layer(automation_button=self._grid[1][2], record_button=self._grid[2][1]) def _setup_m4l_interface(self): self._m4l_interface = M4LInterfaceComponent( controls=self.controls, component_guard=self.component_guard, priority=10 ) self._m4l_interface.name = "M4LInterface" 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 def _setup_translations(self): controls = [] for control in self.controls: controls.append(control) self._translations = TranslationComponent(controls, 10) self._translations.name = "TranslationComponent" self._translations.set_enabled(False) def _setup_OSC_layer(self): self._OSC_id = 0 if hasattr(__builtins__, "control_surfaces") or ( isinstance(__builtins__, dict) and "control_surfaces" in __builtins__.keys() ): for cs in __builtins__["control_surfaces"]: if cs is self: break elif isinstance(cs, DS1): self._OSC_id += 1 self._prefix = "/Live/DS1/" + str(self._OSC_id) self._outPrt = OSC_OUTPORT if not self.oscServer is None: self.oscServer.shutdown() self.oscServer = RemixNet.OSCServer("localhost", self._outPrt, "localhost", 10001) def _setup_main_modes(self): self._main_modes = ToggledModesComponent(name="MainModes") self._main_modes.add_mode("Main", [self._mixer.main_layer, self.main_mode_message]) self._main_modes.add_mode("Select", [self._mixer.select_layer, self.select_mode_message]) self._main_modes.add_mode("Clips", [self._session.clips_layer, self.clip_mode_message]) self._main_modes.layer = Layer(priority=4, toggle_button=self._grid[2][2]) self._main_modes.set_enabled(True) self._main_modes.selected_mode = "Main" def _notify_descriptors(self): if OSC_TRANSMIT: for pad in self._pad: self.oscServer.sendOSC( self._prefix + "/" + pad.name + "/lcd_name/", str(self.generate_strip_string(pad._descriptor)) ) for touchpad in self._touchpad: self.oscServer.sendOSC( self._prefix + "/" + touchpad.name + "/lcd_name/", str(self.generate_strip_string(touchpad._descriptor)), ) for button in self._button: self.oscServer.sendOSC( self._prefix + "/" + button.name + "/lcd_name/", str(self.generate_strip_string(button._descriptor)) ) def _get_devices(self, track): def dig(container_device): contained_devices = [] if container_device.can_have_chains: for chain in container_device.chains: for chain_device in chain.devices: for item in dig(chain_device): contained_devices.append(item) else: contained_devices.append(container_device) return contained_devices devices = [] for device in track.devices: for item in dig(device): devices.append(item) # self.log_message('appending ' + str(item)) return devices """called on timer""" def update_display(self): super(DS1, self).update_display() self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if self.flash_status > 0: for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer) """m4l bridge""" def _on_device_name_changed(self): name = self._device.device_name_data_source().display_string() self._monobridge._send("Device_Name", "lcd_name", str(self.generate_strip_string("Device"))) self._monobridge._send("Device_Name", "lcd_value", str(self.generate_strip_string(name))) self.touched() if OSC_TRANSMIT: self.oscServer.sendOSC(self._prefix + "/glob/device/", str(self.generate_strip_string(name))) def _on_device_bank_changed(self): name = "No Bank" if is_device(self._device._device): name, _ = self._device._current_bank_details() self._monobridge._send("Device_Bank", "lcd_name", str(self.generate_strip_string("Bank"))) self._monobridge._send("Device_Bank", "lcd_value", str(self.generate_strip_string(name))) self.touched() def _on_device_chain_changed(self): name = " " if ( is_device(self._device._device) and self._device._device.canonical_parent and isinstance(self._device._device.canonical_parent, Live.Chain.Chain) ): name = self._device._device.canonical_parent.name self._monobridge._send("Device_Chain", "lcd_name", str(self.generate_strip_string("Chain"))) self._monobridge._send("Device_Chain", "lcd_value", str(self.generate_strip_string(name))) self.touched() def generate_strip_string(self, display_string): NUM_CHARS_PER_DISPLAY_STRIP = 12 if not display_string: return " " * NUM_CHARS_PER_DISPLAY_STRIP else: display_string = str(display_string) if (len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and ( display_string.endswith("dB") and (display_string.find(".") != -1) ): display_string = display_string[:-2] if len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1): for um in [" ", "i", "o", "u", "e", "a"]: while (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1): um_pos = display_string.rfind(um, 1) display_string = display_string[:um_pos] + display_string[(um_pos + 1) :] else: display_string = display_string.center((NUM_CHARS_PER_DISPLAY_STRIP - 1)) ret = u"" for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)): if (ord(display_string[i]) > 127) or (ord(display_string[i]) < 0): ret += " " else: ret += display_string[i] ret += " " ret = ret.replace(" ", "_") assert len(ret) == NUM_CHARS_PER_DISPLAY_STRIP return ret def notification_to_bridge(self, name, value, sender): # self.log_message('monobridge:' + str(name) + str(value)) if isinstance(sender, MonoEncoderElement): if OSC_TRANSMIT: self.oscServer.sendOSC( self._prefix + "/" + sender.name + "/lcd_name/", str(self.generate_strip_string(name)) ) self.oscServer.sendOSC( self._prefix + "/" + sender.name + "/lcd_value/", str(self.generate_strip_string(value)) ) self._monobridge._send(sender.name, "lcd_name", str(self.generate_strip_string(name))) self._monobridge._send(sender.name, "lcd_value", str(self.generate_strip_string(value))) else: self._monobridge._send(name, "lcd_name", str(self.generate_strip_string(name))) self._monobridge._send(name, "lcd_value", str(self.generate_strip_string(value))) if OSC_TRANSMIT: self.oscServer.sendOSC(self._prefix + "/" + name + "/lcd_name/", str(self.generate_strip_string(name))) self.oscServer.sendOSC( self._prefix + "/" + name + "/lcd_value/", str(self.generate_strip_string(value)) ) def touched(self): if self._touched is 0: self._monobridge._send("touch", "on") self.schedule_message(2, self.check_touch) self._touched += 1 def check_touch(self): if self._touched > 5: self._touched = 5 elif self._touched > 0: self._touched -= 1 if self._touched is 0: self._monobridge._send("touch", "off") else: self.schedule_message(2, self.check_touch) """general functionality""" def disconnect(self): if not self.oscServer is None: self.oscServer.shutdown() self.oscServer = None self.log_message("--------------= DS1 log closed =--------------") super(DS1, self).disconnect() def _can_auto_arm_track(self, track): routing = track.current_input_routing return routing == "Ext: All Ins" or routing == "All Ins" or routing.startswith("DS1 Input") # self._main_modes.selected_mode in ['Sends', 'Device'] and def _on_selected_track_changed(self): super(DS1, self)._on_selected_track_changed() def handle_sysex(self, midi_bytes): # self.log_message('sysex: ' + str(midi_bytes)) if len(midi_bytes) > 14: if midi_bytes[3:10] == tuple([6, 2, 0, 1, 97, 1, 0]): if not self._connected: self._connected = True self._initialize_hardware()
class Cntrlr(ControlSurface): __module__ = __name__ __doc__ = " Monomodular controller script for Livid CNTRLR " def __init__(self, *a, **k): super(Cntrlr, self).__init__(*a, **k) self._version_check = 'b996' self._host_name = 'Cntrlr' self._color_type = 'OhmRGB' self._client = [None for index in range(4)] self._active_client = None self._rgb = 0 self._timer = 0 self._touched = 0 self.flash_status = 1 self._skin = Skin(CntrlrColors) self._device_selection_follows_track_selection = FOLLOW with self.component_guard(): self._setup_monobridge() self._setup_controls() self._define_sysex() self._setup_transport_control() self._setup_autoarm() self._setup_session_recording_component() self._setup_mixer_control() self._setup_send_resets() self._setup_session_control() self._setup_device_control() self._setup_device_selector() self._setup_translations() self._setup_viewcontrol() self._setup_mod() self._setup_instrument() self._setup_modswitcher() self._setup_modes() self._setup_m4l_interface() self._on_device_changed.subject = self.song() self.set_feedback_channels(range(14, 15)) self._main_modes.selected_mode = 'MixMode' self.schedule_message(1, self._open_log) def _open_log(self): self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) + " " + str(self._version_check) + " log opened =>>>>>>>>>>>>>>>>>>>") self.show_message(str(self._host_name) + ' Control Surface Loaded') def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_controls(self): is_momentary = True self._fader = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self) for index in range(8)] self._dial_left = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_KNOBS_LEFT[index], Live.MidiMap.MapMode.absolute, 'Dial_Left_' + str(index), CNTRLR_KNOBS_LEFT[index], self) for index in range(12)] self._dial_right = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_KNOBS_RIGHT[index], Live.MidiMap.MapMode.absolute, 'Dial_Right_' + str(index), CNTRLR_KNOBS_RIGHT[index], self) for index in range(12)] self._encoder = [CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), CNTRLR_DIALS[index], self) for index in range(12)] self._encoder_button = [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CNTRLR_DIAL_BUTTONS[index], name = 'Encoder_Button_' + str(index), script = self, skin = self._skin) for index in range(12)] self._grid = [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CNTRLR_GRID[index], name = 'Grid_' + str(index), script = self, skin = self._skin) for index in range(16)] self._button = [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CNTRLR_BUTTONS[index], name = 'Button_' + str(index), script = self, skin = self._skin) for index in range(32)] self._knobs = self._dial_left + self._dial_right self._fader_matrix = ButtonMatrixElement(name = 'Fader_Matrix', rows = [self._fader]) self._matrix = ButtonMatrixElement(name = 'Matrix', rows = [self._grid[index*4:(index*4)+4] for index in range(4)]) self._knob_left_matrix = ButtonMatrixElement(name = 'Knob_Left_Matrix', rows = [self._dial_left[index*4:(index*4)+4] for index in range(3)]) self._knob_right_matrix = ButtonMatrixElement(name = 'Knob_Right_Matrix', rows = [self._dial_right[index*4:(index*4)+4] for index in range(3)]) self._dial_matrix = ButtonMatrixElement(name = 'Dial_Matrix', rows = [self._encoder[index*4:(index*4)+4] for index in range(3)]) self._dial_button_matrix = ButtonMatrixElement(name = 'Dial_Button_Matrix', rows = [self._encoder_button[index*4:(index*4)+4] for index in range(1,3)]) self._key_matrix = ButtonMatrixElement(name = 'Key_Matrix', rows = [self._button[0:16], self._button[16:32]]) self._translated_controls = self._fader + self._knobs + self._encoder[4:] + self._grid + self._button def _define_sysex(self): self.encoder_navigation_on = SendSysexMode(script = self, sysex = (240, 0, 1, 97, 8, 17, 15, 0, 0, 0, 0, 0, 0, 0, 247)) self.encoder_navigation_off = SendSysexMode(script = self, sysex = (240, 0, 1, 97, 8, 17, 0, 0, 0, 0, 0, 0, 0, 0, 247)) def _setup_transport_control(self): self._transport = CntrlrTransportComponent() self._transport.name = 'Transport' self._transport.layer = Layer(priority = 4, play_button = self._button[28], record_button = self._button[30], stop_button = self._button[29]) def _setup_autoarm(self): self._auto_arm = AutoArmComponent(name='Auto_Arm') self._auto_arm.can_auto_arm_track = self._can_auto_arm_track def _setup_session_recording_component(self): self._clip_creator = ClipCreator() self._clip_creator.name = 'ClipCreator' self._recorder = CntrlrSessionRecordingComponent(self._clip_creator, ViewControlComponent()) # is_enabled = False) self._recorder.layer = Layer(priority = 4, new_button = self._button[28], record_button = self._button[29], automation_button = self._button[30]) self._recorder.set_enabled(False) def _setup_mixer_control(self): is_momentary = True self._num_tracks = (4) self._mixer = MixerComponent(num_tracks = 4, num_returns = 2, name = 'Mixer', auto_name = True, invert_mute_feedback = True) self._mixer.set_track_offset(0) if self._mixer.channel_strip(0)._track: self.song().view.selected_track = self._mixer.channel_strip(0)._track self._mixer.main_faders_layer = AddLayerMode(self._mixer, Layer(priority = 4, volume_controls = self._fader_matrix.submatrix[:4, :], return_controls = self._fader_matrix.submatrix[4:6, :], prehear_volume_control = self._fader[6],)) self._mixer.main_buttons_layer = AddLayerMode(self._mixer, Layer(priority = 4, mute_buttons = self._key_matrix.submatrix[:4, 1:], arm_buttons = self._key_matrix.submatrix[4:8, :1], solo_buttons = self._key_matrix.submatrix[:4, :1], track_select_buttons = self._key_matrix.submatrix[4:8, 1:],)) self._mixer.stop_layer = AddLayerMode(self._mixer, Layer(priority = 4, stop_clip_buttons = self._key_matrix.submatrix[8:12, 1:],)) self._mixer.main_knobs_layer = AddLayerMode(self._mixer, Layer(priority = 4, send_controls = self._knob_left_matrix.submatrix[:, :2], pan_controls = self._knob_left_matrix.submatrix[:, 2:], eq_gain_controls = self._knob_right_matrix)) self._mixer.master_fader_layer = AddLayerMode(self._mixer.master_strip(), Layer(priority = 4, volume_control = self._fader[7])) self._mixer.instrument_buttons_layer = AddLayerMode(self._mixer, Layer(priority = 4, mute_buttons = self._key_matrix.submatrix[:4, 1:], track_select_buttons = self._key_matrix.submatrix[4:8, 1:],)) self._mixer.dial_nav_layer = AddLayerMode(self._mixer, Layer(priority = 4, track_select_dial = self._encoder[3])) def _setup_send_resets(self): self._send_reset = CntrlrResetSendsComponent(self) self._send_reset.name = 'Sends_Reset' self._send_reset.layer = Layer(buttons = self._key_matrix.submatrix[8:12, :1]) def _setup_session_control(self): self._session = CntrlrSessionComponent(num_tracks = 4, num_scenes = 4, name = 'Session', enable_skinning = True, auto_name = True) self._session.set_mixer(self._mixer) self.set_highlighting_session_component(self._session) self._session.layer = Layer(priority = 4, clip_launch_buttons = self._matrix) self._session.nav_layer = AddLayerMode(self._session, Layer(priority = 4, scene_bank_down_button = self._button[14], scene_bank_up_button = self._button[15], track_bank_left_button = self._button[12], track_bank_right_button = self._button[13])) self._session.dial_nav_layer = AddLayerMode(self._session, Layer(priority = 4, scene_select_dial = self._encoder[2])) self._session_zoom = SessionZoomingComponent(session = self._session, name = 'Session_Overview', enable_skinning = True) # is_enabled = False) # self._session_zoom.buttons_layer = AddLayerMode(self._session_zoom, Layer(priority = 4, button_matrix = self._matrix)) self._session.set_offsets(0, 0) def _setup_device_control(self): self._device_selection_follows_track_selection = FOLLOW self._device = DeviceComponent() self._device.name = 'Device_Component' self._device._is_banking_enabled = self.device_is_banking_enabled(self._device) self.set_device_component(self._device) self._device.layer = Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:, 1:3], lock_button = self._encoder_button[5], on_off_button = self._encoder_button[4], bank_prev_button = self._encoder_button[6], bank_next_button = self._encoder_button[7]) self._device_navigator = DeviceNavigator(self._device, self._mixer, self) self._device_navigator.name = 'Device_Navigator' self._device_navigator.layer = Layer(priority = 4, prev_button = self._encoder_button[8], next_button = self._encoder_button[9], prev_chain_button = self._encoder_button[10], next_chain_button = self._encoder_button[11],) def _setup_device_selector(self): self._device_selector = DeviceSelectorComponent(self) # is_enabled = False) self._device_selector.name = 'Device_Selector' self._device_selector.layer = Layer(matrix = self._matrix.submatrix[:, :3]) self._device_selector.set_enabled(False) def _setup_translations(self): self._translations = TranslationComponent(self._translated_controls, user_channel_offset = 4, channel = 4) # is_enabled = False) self._translations.name = 'TranslationComponent' self._translations.layer = Layer(priority = 10,) self._translations.selector_layer = AddLayerMode(self._translations, Layer(priority = 10, channel_selector_buttons = self._dial_button_matrix)) self._translations.set_enabled(False) self._optional_translations = CompoundMode(TranslationComponent(controls = self._fader, user_channel_offset = 4, channel = 4, name = 'FaderTranslation', is_enabled = False, layer = Layer(priority = 10)) if FADER_BANKING else None, TranslationComponent(controls = self._knobs, user_channel_offset = 4, channel = 4, name = 'DialTranslation', is_enabled = False, layer = Layer(priority = 10)) if DIAL_BANKING else None) def _setup_mod(self): self.monomodular = get_monomodular(self) self.monomodular.name = 'monomodular_switcher' self.modhandler = CntrlrModHandler(self) # is_enabled = False) self.modhandler.name = 'ModHandler' self.modhandler.set_lock_button(self._encoder_button[1]) self.modhandler.layer = Layer(priority = 8, cntrlr_encoder_grid = self._dial_matrix, cntrlr_encoder_button_grid = self._dial_button_matrix, cntrlr_grid = self._matrix, cntrlr_keys = self._key_matrix,) #parameter_controls = self._dial_matrix) def _setup_instrument(self): self._grid_resolution = self.register_disconnectable(GridResolution()) self._c_instance.playhead.enabled = True self._playhead_element = PlayheadElement(self._c_instance.playhead) self._playhead_element.reset() self._instrument = CntrlrMonoInstrumentComponent(self, self._skin, grid_resolution = self._grid_resolution, name = 'InstrumentModes') # is_enabled = False) #self._instrument.layer = Layer(priority = 10, shift_mode_button = self._button[31]) self._instrument.shift_button_layer = AddLayerMode(self._instrument, Layer(priority = 5, shift_mode_button = self._button[31])) self._instrument.audioloop_layer = LayerMode(self._instrument, Layer(priority = 4, loop_selector_matrix = self._key_matrix.submatrix[:, :1])) self._instrument.keypad_shift_layer = AddLayerMode(self._instrument, Layer(priority = 4, scale_up_button = self._button[13], scale_down_button = self._button[12], offset_up_button = self._button[11], offset_down_button = self._button[10], vertical_offset_up_button = self._button[9], vertical_offset_down_button = self._button[8], split_button = self._button[14], sequencer_button = self._button[15])) self._instrument.drumpad_shift_layer = AddLayerMode(self._instrument, Layer(priority = 4, scale_up_button = self._button[13], scale_down_button = self._button[12], drum_offset_up_button = self._button[11], drum_offset_down_button = self._button[10], drumpad_mute_button = self._button[9], drumpad_solo_button = self._button[8], split_button = self._button[14], sequencer_button = self._button[15])) self._instrument._keypad.main_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, keypad_matrix = self._matrix)) self._instrument._keypad.sequencer_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, playhead = self._playhead_element, keypad_matrix = self._matrix, sequencer_matrix = self._key_matrix.submatrix[:,:1])) self._instrument._keypad.split_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, keypad_matrix = self._matrix, split_matrix = self._key_matrix.submatrix[:8,:1])) self._instrument._keypad.sequencer_shift_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, keypad_matrix = self._matrix, loop_selector_matrix = self._key_matrix.submatrix[:8, :1], quantization_buttons = self._key_matrix.submatrix[:7, 1:], follow_button = self._button[23])) self._instrument._drumpad.main_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, drumpad_matrix = self._matrix)) self._instrument._drumpad.sequencer_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, playhead = self._playhead_element, drumpad_matrix = self._matrix, sequencer_matrix = self._key_matrix.submatrix[:,:1])) self._instrument._drumpad.split_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, drumpad_matrix = self._matrix, split_matrix = self._key_matrix.submatrix[:8,:1])) self._instrument._drumpad.sequencer_shift_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, drumpad_matrix = self._matrix, loop_selector_matrix = self._key_matrix.submatrix[:8, :1], quantization_buttons = self._key_matrix.submatrix[:7, 1:], follow_button = self._button[23])) self._instrument.set_enabled(False) def _setup_modswitcher(self): self._modswitcher = ModesComponent(name = 'ModSwitcher') # is_enabled = False) #self._modswitcher.add_mode('instrument', [self._optional_translations]) self._modswitcher.add_mode('mod', [self.modhandler, self._optional_translations]) self._modswitcher.add_mode('instrument', [self._instrument, self._instrument.shift_button_layer, self._optional_translations]) self._modswitcher.set_enabled(False) def _setup_viewcontrol(self): self._view_control = ViewControlComponent(name='View_Control')# is_enabled = False) self._view_control.main_layer = AddLayerMode(self._view_control, Layer(prev_track_button=self._button[24], next_track_button= self._button[25], next_scene_button=self._button[27], prev_scene_button = self._button[26])) #self._view_control.set_enabled(False) self._view_control.selector_layer = AddLayerMode(self._view_control, Layer(priority = 8, prev_track_button = self._grid[12], next_track_button = self._grid[13], next_scene_button = self._grid[15], prev_scene_button = self._grid[14])) def _setup_modes(self): main_buttons=CompoundMode(self._mixer.main_buttons_layer, self._mixer.stop_layer, self._transport, self._send_reset, self._session.nav_layer) main_buttons_instrument=CompoundMode(self._mixer.main_buttons_layer, self._recorder, self._view_control.main_layer) main_faders=CompoundMode(self._mixer.main_faders_layer, self._mixer.master_fader_layer) bottom_buttons=CompoundMode(self._mixer.instrument_buttons_layer, self._recorder, self._view_control.main_layer) self._instrument._main_modes = ModesComponent(name = 'InstrumentModes') self._instrument._main_modes.add_mode('disabled', [main_buttons_instrument, main_faders, self._mixer.main_knobs_layer, self._device, self._session, self._recorder, self._view_control.main_layer, self._send_reset, self._session.nav_layer,]) self._instrument._main_modes.add_mode('drumpad', [self._instrument._drumpad.main_layer, main_buttons_instrument, self._send_reset, self._session.nav_layer]) self._instrument._main_modes.add_mode('drumpad_split', [self._instrument._drumpad.split_layer, self._send_reset, self._session.nav_layer]) self._instrument._main_modes.add_mode('drumpad_sequencer', [self._instrument._drumpad.sequencer_layer, bottom_buttons]) self._instrument._main_modes.add_mode('drumpad_shifted', [self._instrument._drumpad.main_layer, self._instrument.drumpad_shift_layer, main_buttons_instrument, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('drumpad_split_shifted', [self._instrument._drumpad.split_layer, self._instrument.drumpad_shift_layer, bottom_buttons, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('drumpad_sequencer_shifted', [self._instrument._drumpad.sequencer_shift_layer, self._instrument.drumpad_shift_layer, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('keypad', [self._instrument._keypad.main_layer, main_buttons_instrument, self._send_reset, self._session.nav_layer]) self._instrument._main_modes.add_mode('keypad_split', [self._instrument._keypad.split_layer, bottom_buttons, self._send_reset, self._session.nav_layer]) self._instrument._main_modes.add_mode('keypad_sequencer', [self._instrument._keypad.sequencer_layer, bottom_buttons]) self._instrument._main_modes.add_mode('keypad_shifted', [self._instrument._keypad.main_layer, self._instrument.keypad_shift_layer, main_buttons_instrument, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('keypad_split_shifted', [self._instrument._keypad.split_layer, self._instrument.keypad_shift_layer, bottom_buttons, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('keypad_sequencer_shifted', [self._instrument._keypad.sequencer_shift_layer, self._instrument.keypad_shift_layer, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('audioloop', [self._instrument.audioloop_layer, self._session, bottom_buttons, self._recorder, self._view_control.main_layer]) self._instrument.register_component(self._instrument._main_modes) self._instrument.set_enabled(False) self._session_modes = ModesComponent(name = 'SessionModes', is_enabled = False) self._session_modes.add_mode('Session', [self._session]) self._session_modes.add_mode('SessionZoom', [self._session_zoom.buttons_layer], behaviour = BicoloredMomentaryBehaviour(color = 'Session.ZoomOn', off_color = 'Session.ZoomOff')) self._session_modes.layer = Layer(priority = 4, SessionZoom_button = self._button[31]) self._session_modes.selected_mode = 'Session' self._main_modes = ModesComponent(name = 'MainModes') self._main_modes.add_mode('MixMode', [main_buttons, main_faders, self._mixer.main_knobs_layer, self._device, self._session_modes, self._session.nav_layer,]) # self._session.dial_nav_layer, self._mixer.dial_nav_layer, self.encoder_navigation_on]) self._main_modes.add_mode('ModSwitcher', [main_faders, self._mixer.main_knobs_layer, self._modswitcher], behaviour = DefaultedBehaviour(default_mode = 'MixMode', color = 'ModeButtons.ModSwitcher', off_color = 'ModeButtons.ModSwitcherDisabled')) self._main_modes.add_mode('Translations', [main_faders, self._mixer.main_knobs_layer, self._translations, DelayMode(self._translations.selector_layer)], behaviour = DefaultedBehaviour(default_mode = 'MixMode', color = 'ModeButtons.Translations', off_color = 'ModeButtons.TranslationsDisabled')) self._main_modes.add_mode('DeviceSelector', [self._device_selector, main_buttons, main_faders, self._mixer.main_knobs_layer, self._device, self._device_navigator, self._view_control.selector_layer], behaviour = ColoredCancellableBehaviourWithRelease(color = 'ModeButtons.DeviceSelector', off_color = 'ModeButtons.DeviceSelectorDisabled')) self._main_modes.layer = Layer(priority = 4, ModSwitcher_button = self._encoder_button[0], Translations_button = self._encoder_button[3], DeviceSelector_button = self._encoder_button[2]) def _setup_m4l_interface(self): self._m4l_interface = MonoM4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard, priority = 10) self._m4l_interface.name = "M4LInterface" 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 def _can_auto_arm_track(self, track): routing = track.current_input_routing return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith('Cntrlr Input') @subject_slot('appointed_device') def _on_device_changed(self): debug('appointed device changed, script') self.schedule_message(2, self._update_modswitcher) def _on_selected_track_changed(self): super(Cntrlr, self)._on_selected_track_changed() self.schedule_message(2, self._update_modswitcher) def _update_modswitcher(self): debug('update modswitcher', self.modhandler.active_mod()) if self.modhandler.active_mod(): self._modswitcher.selected_mode = 'mod' else: self._modswitcher.selected_mode = 'instrument' def reset_controlled_track(self, track = None, *a): if not track: track = self.song().view.selected_track self.set_controlled_track(track) def set_controlled_track(self, track = None, *a): if isinstance(track, Live.Track.Track): super(Cntrlr, self).set_controlled_track(track) else: self.release_controlled_track() """called on timer""" def update_display(self): super(Cntrlr, self).update_display() #since we are overriding this from the inherited method, we need to call the original routine as well self._timer = (self._timer + 1) % 256 #each 100/60ms, increase the self._timer property by one. Start over at 0 when we hit 256 self.modhandler.send_ring_leds() #if local rings are turned off, then we need to send the new values if they've changed self.flash() #call the flash method below def flash(self): if(self.flash_status > 0): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer) """m4l lcd bridge""" def generate_strip_string(self, display_string): NUM_CHARS_PER_DISPLAY_STRIP = 12 if (not display_string): return (' ' * NUM_CHARS_PER_DISPLAY_STRIP) if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.endswith('dB') and (display_string.find('.') != -1))): display_string = display_string[:-2] if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)): for um in [' ', 'i', 'o', 'u', 'e', 'a']: while ((len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1)): um_pos = display_string.rfind(um, 1) display_string = (display_string[:um_pos] + display_string[(um_pos + 1):]) else: display_string = display_string.center((NUM_CHARS_PER_DISPLAY_STRIP - 1)) ret = u'' for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)): if ((ord(display_string[i]) > 127) or (ord(display_string[i]) < 0)): ret += ' ' else: ret += display_string[i] ret += ' ' ret = ret.replace(' ', '_') assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP) return ret def notification_to_bridge(self, name, value, sender): if(isinstance(sender, (MonoEncoderElement, CodecEncoderElement))): pn = str(self.generate_strip_string(name)) pv = str(self.generate_strip_string(value)) self._monobridge._send(sender.name, 'lcd_name', pn) self._monobridge._send(sender.name, 'lcd_value', pv) def touched(self): if self._touched is 0: self._monobridge._send('touch', 'on') self.schedule_message(2, self.check_touch) self._touched +=1 def check_touch(self): if self._touched > 5: self._touched = 5 elif self._touched > 0: self._touched -= 1 if self._touched is 0: self._monobridge._send('touch', 'off') else: self.schedule_message(2, self.check_touch) def handle_sysex(self, midi_bytes): pass def disconnect(self): self.log_message("<<<<<<<<<<<<<<<<<<<<<<<<< " + str(self._host_name) + " log closed >>>>>>>>>>>>>>>>>>>>>>>>>") super(Cntrlr, self).disconnect() def restart_monomodular(self): #debug('restart monomodular') self.modhandler.disconnect() with self.component_guard(): self._setup_mod() def _get_num_tracks(self): return self.num_tracks """a closure fix for banking when we deassign the bank buttons and still want to change bank indexes""" def device_is_banking_enabled(self, device): def _is_banking_enabled(): return True return _is_banking_enabled
class DS1(ControlSurface): __module__ = __name__ __doc__ = " DS1 controller script " def __init__(self, c_instance): super(DS1, self).__init__(c_instance) self._connected = False self._host_name = 'DS1' self.oscServer = None self._rgb = 0 self._timer = 0 self.flash_status = 1 self._touched = 0 self._update_linked_device_selection = None self._skin = Skin(DS1Colors) with self.component_guard(): self._setup_monobridge() self._setup_controls() self._setup_m4l_interface() self._define_sysex() self._initialize_hardware() self._setup_mixer_control() self._setup_session_control() self._setup_transport_control() self._setup_device_control() self._setup_session_recording_component() #self._setup_translations() self._setup_main_modes() #self._device.add_device_listener(self._on_new_device_set) self.log_message( "<<<<<<<<<<<<<<<<<= DS1 log opened =>>>>>>>>>>>>>>>>>>>>>") #self.schedule_message(3, self._initialize_hardware) """script initialization methods""" def _initialize_hardware(self): self.local_control_off.enter_mode() self.encoder_absolute_mode.enter_mode() self.encoder_speed_sysex.enter_mode() def _check_connection(self): if not self._connected: self._send_midi(QUERYSURFACE) self.schedule_message(100, self._check_connection) def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_controls(self): is_momentary = True self._fader = [ MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, DS1_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self) for index in range(8) ] for fader in self._fader: fader._mapping_feedback_delay = -1 self._dial = [[ MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, DS1_DIALS[x][y], Live.MidiMap.MapMode.absolute, 'Dial_' + str(x) + '_' + str(y), x + (y * 5), self) for x in range(8) ] for y in range(5)] for row in self._dial: for dial in row: dial._mapping_feedback_delay = -1 self._side_dial = [ MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, DS1_SIDE_DIALS[x], Live.MidiMap.MapMode.absolute, 'Side_Dial_' + str(x), x, self) for x in range(4) ] for dial in self._side_dial: dial._mapping_feedback_delay = -1 self._encoder = [ MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, DS1_ENCODERS[x], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(x), x, self) for x in range(4) ] for encoder in self._encoder: encoder._mapping_feedback_delay = -1 self._encoder_button = [ MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, DS1_ENCODER_BUTTONS[index], 'EncoderButton_' + str(index), self, skin=self._skin) for index in range(4) ] self._master_fader = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, DS1_MASTER, Live.MidiMap.MapMode.absolute, 'MasterFader', 0, self) self._button = [ MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, DS1_BUTTONS[index], 'Button_' + str(index), self, skin=self._skin) for index in range(16) ] self._grid = [[ MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, DS1_GRID[x][y], 'Button_' + str(x) + '_' + str(y), self, skin=self._skin) for x in range(3) ] for y in range(3)] self._dummy = [ MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, 120 + x, Live.MidiMap.MapMode.absolute, 'Dummy_Dial_' + str(x), x, self) for x in range(5) ] self._fader_matrix = ButtonMatrixElement(name='FaderMatrix', rows=[self._fader]) self._top_buttons = ButtonMatrixElement(name='TopButtonMatrix', rows=[self._button[:8]]) self._bottom_buttons = ButtonMatrixElement(name='BottomButtonMatrix', rows=[self._button[8:]]) self._dial_matrix = ButtonMatrixElement(name='DialMatrix', rows=self._dial) self._side_dial_matrix = ButtonMatrixElement(name='SideDialMatrix', rows=[self._side_dial]) self._encoder_matrix = ButtonMatrixElement(name='EncoderMatrix', rows=[self._encoder]) self._encoder_button_matrix = ButtonMatrixElement( name='EncoderButtonMatrix', rows=[self._encoder_button]) self._grid_matrix = ButtonMatrixElement(name='GridMatrix', rows=self._grid) self._selected_parameter_controls = ButtonMatrixElement( name='SelectedParameterControls', rows=[self._dummy + self._encoder[:1] + self._encoder[2:]]) def _define_sysex(self): self._livid_settings = LividSettings(model=16, control_surface=self) self.encoder_speed_sysex = SendLividSysexMode( livid_settings=self._livid_settings, call='set_encoder_mapping', message=ENCODER_SPEED) self.encoder_absolute_mode = SendLividSysexMode( livid_settings=self._livid_settings, call='set_encoder_encosion_mode', message=[2]) self.local_control_off = SendLividSysexMode( livid_settings=self._livid_settings, call='set_local_control', message=[0]) self.main_mode_message = DisplayMessageMode(self, 'Mute/Solo Mode') self.select_mode_message = DisplayMessageMode(self, 'Arm/Select Mode') self.clip_mode_message = DisplayMessageMode(self, 'Launch/Stop Mode') def _setup_autoarm(self): self._auto_arm = AutoArmComponent(name='Auto_Arm') self._auto_arm.can_auto_arm_track = self._can_auto_arm_track def _setup_mixer_control(self): self._num_tracks = (8) self._mixer = MixerComponent(script=self, num_tracks=8, num_returns=4, invert_mute_feedback=True, autoname=True) self._mixer.name = 'Mixer' self._mixer.set_track_offset(0) self._mixer.master_strip().set_volume_control(self._master_fader) self._mixer.set_prehear_volume_control(self._side_dial[3]) self._mixer.layer = Layer(volume_controls=self._fader_matrix, track_select_dial=self._encoder[1]) self._strip = [self._mixer.channel_strip(index) for index in range(8)] for index in range(8): self._strip[index].layer = Layer( parameter_controls=self._dial_matrix.submatrix[index:index + 1, :]) self._mixer.selected_strip().layer = Layer( parameter_controls=self._selected_parameter_controls) self._mixer.master_strip().layer = Layer( parameter_controls=self._side_dial_matrix.submatrix[:3, :]) self._mixer.main_layer = AddLayerMode( self._mixer, Layer(solo_buttons=self._bottom_buttons, mute_buttons=self._top_buttons)) self._mixer.select_layer = AddLayerMode( self._mixer, Layer(arm_buttons=self._bottom_buttons, track_select_buttons=self._top_buttons)) self.song().view.selected_track = self._mixer.channel_strip(0)._track self._mixer.set_enabled(True) def _setup_session_control(self): self._session = DS1SessionComponent(num_tracks=8, num_scenes=1, auto_name=True, enable_skinning=True) self._session.set_offsets(0, 0) self._session.set_mixer(self._mixer) self._session.layer = Layer( track_select_dial=ComboElement(self._encoder[1], modifiers=[self._encoder_button[1] ]), scene_bank_up_button=self._grid[0][1], scene_bank_down_button=self._grid[0][2], scene_launch_buttons=self._grid_matrix.submatrix[1:2, 1:2]) self._session.clips_layer = AddLayerMode( self._session, Layer(clip_launch_buttons=self._top_buttons, stop_track_clip_buttons=self._bottom_buttons)) self.set_highlighting_session_component(self._session) self._session._do_show_highlight() def _setup_transport_control(self): self._transport = DS1TransportComponent() self._transport.name = 'Transport' self._transport.layer = Layer( stop_button=self._grid[1][0], play_button=self._grid[0][0], record_button=self._grid[2][0], ) self._transport.set_enabled(True) def _setup_device_control(self): self._device = DeviceComponent() self._device.name = 'Device_Component' self.set_device_component(self._device) self._device_navigator = DeviceNavigator(self._device, self._mixer, self) self._device_navigator.name = 'Device_Navigator' #self._device_selection_follows_track_selection = FOLLOW self._device.device_name_data_source().set_update_callback( self._on_device_name_changed) def _setup_session_recording_component(self): self._clip_creator = ClipCreator() self._clip_creator.name = 'ClipCreator' self._recorder = SessionRecordingComponent(self._clip_creator, ViewControlComponent()) self._recorder.set_enabled(True) self._recorder.layer = Layer( automation_button=self._grid[1][2], record_button=self._grid[2][1], ) def _setup_m4l_interface(self): self._m4l_interface = M4LInterfaceComponent( controls=self.controls, component_guard=self.component_guard, priority=10) self._m4l_interface.name = "M4LInterface" 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 def _setup_translations(self): controls = [] for control in self.controls: controls.append(control) self._translations = TranslationComponent(controls, 10) self._translations.name = 'TranslationComponent' self._translations.set_enabled(False) def _setup_OSC_layer(self): self._OSC_id = 0 if hasattr(__builtins__, 'control_surfaces') or ( isinstance(__builtins__, dict) and 'control_surfaces' in __builtins__.keys()): for cs in __builtins__['control_surfaces']: if cs is self: break elif isinstance(cs, DS1): self._OSC_id += 1 self._prefix = '/Live/DS1/' + str(self._OSC_id) self._outPrt = OSC_OUTPORT if not self.oscServer is None: self.oscServer.shutdown() self.oscServer = RemixNet.OSCServer('localhost', self._outPrt, 'localhost', 10001) def _setup_main_modes(self): self._main_modes = ToggledModesComponent(name='MainModes') self._main_modes.add_mode( 'Main', [self._mixer.main_layer, self.main_mode_message], ) self._main_modes.add_mode( 'Select', [self._mixer.select_layer, self.select_mode_message], ) self._main_modes.add_mode( 'Clips', [self._session.clips_layer, self.clip_mode_message], ) self._main_modes.layer = Layer(priority=4, toggle_button=self._grid[2][2]) self._main_modes.set_enabled(True) self._main_modes.selected_mode = 'Main' def _notify_descriptors(self): if OSC_TRANSMIT: for pad in self._pad: self.oscServer.sendOSC( self._prefix + '/' + pad.name + '/lcd_name/', str(self.generate_strip_string(pad._descriptor))) for touchpad in self._touchpad: self.oscServer.sendOSC( self._prefix + '/' + touchpad.name + '/lcd_name/', str(self.generate_strip_string(touchpad._descriptor))) for button in self._button: self.oscServer.sendOSC( self._prefix + '/' + button.name + '/lcd_name/', str(self.generate_strip_string(button._descriptor))) def _get_devices(self, track): def dig(container_device): contained_devices = [] if container_device.can_have_chains: for chain in container_device.chains: for chain_device in chain.devices: for item in dig(chain_device): contained_devices.append(item) else: contained_devices.append(container_device) return contained_devices devices = [] for device in track.devices: for item in dig(device): devices.append(item) #self.log_message('appending ' + str(item)) return devices """called on timer""" def update_display(self): super(DS1, self).update_display() self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if (self.flash_status > 0): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer) """m4l bridge""" def _on_device_name_changed(self): name = self._device.device_name_data_source().display_string() self._monobridge._send('Device_Name', 'lcd_name', str(self.generate_strip_string('Device'))) self._monobridge._send('Device_Name', 'lcd_value', str(self.generate_strip_string(name))) self.touched() if OSC_TRANSMIT: self.oscServer.sendOSC(self._prefix + '/glob/device/', str(self.generate_strip_string(name))) def _on_device_bank_changed(self): name = 'No Bank' if is_device(self._device._device): name, _ = self._device._current_bank_details() self._monobridge._send('Device_Bank', 'lcd_name', str(self.generate_strip_string('Bank'))) self._monobridge._send('Device_Bank', 'lcd_value', str(self.generate_strip_string(name))) self.touched() def _on_device_chain_changed(self): name = " " if is_device( self._device._device ) and self._device._device.canonical_parent and isinstance( self._device._device.canonical_parent, Live.Chain.Chain): name = self._device._device.canonical_parent.name self._monobridge._send('Device_Chain', 'lcd_name', str(self.generate_strip_string('Chain'))) self._monobridge._send('Device_Chain', 'lcd_value', str(self.generate_strip_string(name))) self.touched() def generate_strip_string(self, display_string): NUM_CHARS_PER_DISPLAY_STRIP = 12 if (not display_string): return (' ' * NUM_CHARS_PER_DISPLAY_STRIP) else: display_string = str(display_string) if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.endswith('dB') and (display_string.find('.') != -1))): display_string = display_string[:-2] if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)): for um in [' ', 'i', 'o', 'u', 'e', 'a']: while ((len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1)): um_pos = display_string.rfind(um, 1) display_string = (display_string[:um_pos] + display_string[(um_pos + 1):]) else: display_string = display_string.center( (NUM_CHARS_PER_DISPLAY_STRIP - 1)) ret = u'' for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)): if ((ord(display_string[i]) > 127) or (ord(display_string[i]) < 0)): ret += ' ' else: ret += display_string[i] ret += ' ' ret = ret.replace(' ', '_') assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP) return ret def notification_to_bridge(self, name, value, sender): #self.log_message('monobridge:' + str(name) + str(value)) if isinstance(sender, MonoEncoderElement): if OSC_TRANSMIT: self.oscServer.sendOSC( self._prefix + '/' + sender.name + '/lcd_name/', str(self.generate_strip_string(name))) self.oscServer.sendOSC( self._prefix + '/' + sender.name + '/lcd_value/', str(self.generate_strip_string(value))) self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name))) self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value))) else: self._monobridge._send(name, 'lcd_name', str(self.generate_strip_string(name))) self._monobridge._send(name, 'lcd_value', str(self.generate_strip_string(value))) if OSC_TRANSMIT: self.oscServer.sendOSC( self._prefix + '/' + name + '/lcd_name/', str(self.generate_strip_string(name))) self.oscServer.sendOSC( self._prefix + '/' + name + '/lcd_value/', str(self.generate_strip_string(value))) def touched(self): if self._touched is 0: self._monobridge._send('touch', 'on') self.schedule_message(2, self.check_touch) self._touched += 1 def check_touch(self): if self._touched > 5: self._touched = 5 elif self._touched > 0: self._touched -= 1 if self._touched is 0: self._monobridge._send('touch', 'off') else: self.schedule_message(2, self.check_touch) """general functionality""" def disconnect(self): if not self.oscServer is None: self.oscServer.shutdown() self.oscServer = None self.log_message("--------------= DS1 log closed =--------------") super(DS1, self).disconnect() def _can_auto_arm_track(self, track): routing = track.current_input_routing return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith( 'DS1 Input') #self._main_modes.selected_mode in ['Sends', 'Device'] and def _on_selected_track_changed(self): super(DS1, self)._on_selected_track_changed() def handle_sysex(self, midi_bytes): #self.log_message('sysex: ' + str(midi_bytes)) if len(midi_bytes) > 14: if midi_bytes[3:10] == tuple([6, 2, 0, 1, 97, 1, 0]): if not self._connected: self._connected = True self._initialize_hardware() # a
class OhmModes(ControlSurface): __module__ = __name__ __doc__ = ' OhmModes controller script ' def __init__(self, c_instance): super(OhmModes, self).__init__(c_instance) self._version_check = 'b996' self._host_name = 'Ohm' self._color_type = 'OhmRGB' self._rgb = 0 self._timer = 0 self._touched = 0 self.flash_status = 1 self._backlight = 127 self._backlight_type = 'static' self._ohm = 127 self._ohm_type = 'static' self._pad_translations = PAD_TRANSLATION self._device_selection_follows_track_selection = FOLLOW self._keys_octave = 5 self._keys_scale = 0 self._tempo_buttons = None with self.component_guard(): self._setup_monobridge() self._setup_controls() self._setup_m4l_interface() self._setup_transport_control() self._setup_mixer_control() self._setup_session_control() self._setup_device_control() self._setup_crossfader() self._setup_translations() self._setup_mod() self._setup_modes() self._assign_page_constants() self._last_device = None self.song().view.add_selected_track_listener(self._update_selected_device) self.show_message('OhmModes Control Surface Loaded') self._send_midi(tuple(switchxfader)) if FORCE_TYPE is True: self._rgb = FORCE_COLOR_TYPE else: self.schedule_message(10, self.query_ohm, None) self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< OhmModes ' + str(self._version_check) + ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>') debug('DEBUG ON for OhmModes script.') def query_ohm(self): self._send_midi(tuple(check_model)) def update_display(self): super(OhmModes, self).update_display() self._timer = (self._timer + 1) % 256 self.flash() self.strobe() def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def get_device_bank(self): return self._device._bank_index def _setup_controls(self): is_momentary = True self._fader = [ None for index in range(8) ] self._dial = [ None for index in range(16) ] self._button = [ None for index in range(8) ] self._menu = [ None for index in range(6) ] for index in range(8): self._fader[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self) for index in range(8): self._button[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self) for index in range(16): self._dial[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), index, self) self._knobs = [] for index in range(12): self._knobs.append(self._dial[index]) for index in range(6): self._menu[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self) self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute) self._crossfader.name = 'Crossfader' self._livid = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self) self._shift_l = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Page_Button_Left', self) self._shift_r = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Page_Button_Right', self) self._matrix = ButtonMatrixElement() self._matrix.name = 'Matrix' self._grid = [ None for index in range(8) ] self._monomod = ButtonMatrixElement() self._monomod.name = 'Monomod' for column in range(8): self._grid[column] = [ None for index in range(8) ] for row in range(8): self._grid[column][row] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, column * 8 + row, 'Grid_' + str(column) + '_' + str(row), self) for row in range(5): button_row = [] for column in range(7): button_row.append(self._grid[column][row]) self._matrix.add_row(tuple(button_row)) for row in range(8): button_row = [] for column in range(8): button_row.append(self._grid[column][row]) self._monomod.add_row(tuple(button_row)) self._dial_matrix = ButtonMatrixElement() for row in range(3): dial_row = [] for column in range(4): dial_row.append(self._dial[column + (row*4)]) self._dial_matrix.add_row(tuple(dial_row)) self._menu_matrix = ButtonMatrixElement([self._menu]) 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 def _setup_translations(self): controls = [] for array in self._grid: for button in array: controls.append(button) if FADER_BANKING: controls = controls + self._dial if DIAL_BANKING: controls = controls + self._dial self._translations = TranslationComponent(controls, USER_CHANNEL) self._translations.layer = Layer(priority = 7, channel_selector_buttons = self._menu_matrix) def _setup_mod(self): self.monomodular = get_monomodular(self) self.monomodular.name = 'monomodular_switcher' self.modhandler = OhmModHandler(self) self.modhandler.name = 'ModHandler' self.modhandler.layer = Layer(priority = 5, grid = self._monomod, nav_up_button = self._menu[2], nav_down_button = self._menu[5], nav_left_button = self._menu[3], nav_right_button = self._menu[4], shift_button = self._menu[1], alt_button = self._menu[0], parameter_controls = self._dial_matrix) self.modhandler.legacy_shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6, channel_buttons = self._monomod.submatrix[:, 1:2], nav_matrix = self._monomod.submatrix[4:8, 2:6])) self.modhandler.shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6, device_selector_matrix = self._monomod.submatrix[:, :1], lock_button = self._livid, key_buttons = self._monomod.submatrix[:, 7:8])) self.modhandler.set_enabled(False) self.modhandler.set_mod_button(self._livid) def _setup_modes(self): self._shift_mode = ShiftModeComponent(self) self._shift_mode.name = 'Shift_Mode' #self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r, self._livid) self._shift_mode.layer = Layer(priority = 4, mode_toggle1 = self._shift_l, mode_toggle2 = self._shift_r, mode_toggle3 = self._livid) self._shift_mode.set_enabled(True) self._scale_mode = ScaleModeComponent(self) self._scale_mode.name = 'Scale_Mode' self._octave_mode = OctaveModeComponent(self) self._octave_mode.name = 'Octave_Mode' def _setup_transport_control(self): self._transport = TransportComponent() self._transport.name = 'Transport' #self._transport.layer = Layer(priority = 4, play_button = self._menu[2], stop_button = self._menu[3]) def _setup_mixer_control(self): global mixer is_momentary = True self._num_tracks = 7 mixer = SpecialMixerComponent(7, 0, True, True) mixer.name = 'Mixer' self._mixer = mixer for index in range(7): mixer.channel_strip(index).set_volume_control(self._fader[index]) for index in range(7): mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index) mixer.track_eq(index).name = 'Mixer_EQ_' + str(index) mixer.channel_strip(index)._invert_mute_feedback = True self.song().view.selected_track = mixer.channel_strip(0)._track def _setup_session_control(self): global session is_momentary = True num_tracks = 7 num_scenes = 5 session = SessionComponent(num_tracks, num_scenes) session.name = 'Session' self._session = session session.set_offsets(0, 0) self._scene = [ None for index in range(6) ] for row in range(num_scenes): self._scene[row] = session.scene(row) self._scene[row].name = 'Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_' + str(row) session.set_mixer(self._mixer) session.set_show_highlight(True) self._session_zoom = SessionZoomingComponent(session) self._session_zoom.name = 'Session_Overview' self.set_highlighting_session_component(self._session) def _assign_session_colors(self): self.log_message('assign session colors') num_tracks = 7 num_scenes = 5 self._session.set_stop_clip_value(STOP_CLIP_COLOR[self._rgb]) for row in range(num_scenes): for column in range(num_tracks): self._scene[row].clip_slot(column).set_triggered_to_play_value(CLIP_TRIGD_TO_PLAY_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_triggered_to_record_value(CLIP_TRIGD_TO_RECORD_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_stopped_value(CLIP_STOPPED_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_recording_value(CLIP_RECORDING_COLOR[self._rgb]) self._session_zoom.set_stopped_value(ZOOM_STOPPED_COLOR[self._rgb]) self._session_zoom.set_playing_value(ZOOM_PLAYING_COLOR[self._rgb]) self._session_zoom.set_selected_value(ZOOM_SELECTED_COLOR[self._rgb]) for row in range(8): for column in range(8): self._grid[column][row].set_force_next_value() self._session.on_scene_list_changed() self._shift_mode.update() def _setup_device_control(self): self._device = DeviceComponent() self._device.name = 'Device_Component' self.set_device_component(self._device) self._device_navigator = DetailViewControllerComponent() self._device_navigator.name = 'Device_Navigator' self._device_selection_follows_track_selection = FOLLOW def device_follows_track(self, val): self._device_selection_follows_track_selection = val == 1 return self def _setup_crossfader(self): self._mixer.set_crossfader_control(self._crossfader) def disconnect(self): """clean things up on disconnect""" self.song().view.remove_selected_track_listener(self._update_selected_device) self.log_message(time.strftime('%d.%m.%Y %H:%M:%S', time.localtime()) + '--------------= OhmModes log closed =--------------') super(OhmModes, self).disconnect() rebuild_sys() def _get_num_tracks(self): return self.num_tracks def flash(self): if(self.flash_status > 0): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer) def strobe(self): if self._backlight_type != 'static': if self._backlight_type is 'pulse': self._backlight = int(math.fabs(self._timer * 16 % 64 - 32) + 32) if self._backlight_type is 'up': self._backlight = int(self._timer * 8 % 64 + 16) if self._backlight_type is 'down': self._backlight = int(math.fabs(int(self._timer * 8 % 64 - 64)) + 16) self._send_midi(tuple([176, 27, int(self._backlight)])) if self._ohm_type != 'static': if self._ohm_type is 'pulse': self._ohm = int(math.fabs(self._timer * 16 % 64 - 32) + 32) if self._ohm_type is 'up': self._ohm = int(self._timer * 8 % 64 + 16) if self._ohm_type is 'down': self._ohm = int(math.fabs(int(self._timer * 8 % 64 - 64)) + 16) self._send_midi(tuple([176, 63, int(self._ohm)])) self._send_midi(tuple([176, 31, int(self._ohm)])) def deassign_matrix(self): with self.component_guard(): self.modhandler.set_enabled(False) self._translations.set_enabled(False) #self.assign_alternate_mappings(0) self._scale_mode.set_mode_buttons(None) self._scale_mode.set_enabled(False) self._octave_mode.set_mode_buttons(None) self._octave_mode.set_enabled(False) self._session_zoom.set_enabled(False) self._session_zoom.set_nav_buttons(None, None, None, None) self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) self._transport.set_enabled(False) for column in range(4): self._mixer.track_eq(column)._gain_controls = None self._mixer.track_eq(column).set_enabled(False) for column in range(7): self._mixer.channel_strip(column).set_crossfade_toggle(None) self._mixer.channel_strip(column).set_mute_button(None) self._mixer.channel_strip(column).set_solo_button(None) self._mixer.channel_strip(column).set_arm_button(None) self._mixer.channel_strip(column).set_send_controls(None) self._mixer.channel_strip(column).set_pan_control(None) self._mixer.track_eq(column).set_enabled(False) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(None) for column in range(8): self._button[column]._on_value = SELECT_COLOR[self._rgb] for row in range(8): #self._grid[column][row].set_channel(0) self._grid[column][row].release_parameter() self._grid[column][row].use_default_message() self._grid[column][row].set_enabled(True) self._grid[column][row].send_value(0, True) self._grid[column][row]._on_value = 127 self._grid[column][row]._off_value = 0 self._grid[column][row].force_next_send() for index in range(6): self._menu[index]._on_value = 127 self._menu[index]._off_value = 0 for index in range(16): self._dial[index].use_default_message() self._dial[index].release_parameter() self._device.set_parameter_controls(None) self._device.set_enabled(False) self._device_navigator.set_enabled(False) self._mixer.update() self._matrix.reset() self.request_rebuild_midi_map() def _assign_page_constants(self): with self.component_guard(): self._session_zoom.set_zoom_button(self._grid[7][7]) self._session_zoom.set_button_matrix(self._matrix) for column in range(7): self._mixer.channel_strip(column).set_select_button(self._button[column]) self._mixer.channel_strip(column).set_volume_control(self._fader[column]) self._mixer.master_strip().set_volume_control(self._fader[7]) self._mixer.master_strip().set_select_button(self._button[7]) self._mixer.set_prehear_volume_control(self._dial[15]) self._transport.set_play_button(self._menu[0]) self._menu[0].send_value(PLAY_COLOR[self._rgb], True) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._transport.set_stop_button(self._menu[1]) self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._menu[1].send_value(STOP_COLOR[self._rgb], True) self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[4]) def assign_page_0(self): with self.component_guard(): self._backlight_type = 'static' self._session_zoom.set_enabled(True) for column in range(7): self._grid[column][5]._on_value = MUTE_COLOR[self._rgb] self._mixer.channel_strip(column).set_mute_button(self._grid[column][5]) self._grid[column][6]._on_value = SOLO_COLOR[self._rgb] self._mixer.channel_strip(column).set_solo_button(self._grid[column][6]) self._grid[column][7]._on_value = ARM_COLOR[self._rgb] self._mixer.channel_strip(column).set_arm_button(self._grid[column][7]) self._mixer.channel_strip(column).set_pan_control(self._dial[column + 8]) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) for column in range(4): self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column], self._dial[column + 4]])) for index in range(5): self._grid[7][index]._off_value = SCENE_LAUNCH_COLOR[self._rgb] self._scene[index].set_launch_button(self._grid[7][index]) self._grid[7][index].set_force_next_value() self._grid[7][index].turn_off() for index in range(4): self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb] self._session.set_track_bank_buttons(self._menu[4], self._menu[3]) self._session.set_scene_bank_buttons(self._menu[5], self._menu[2]) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) #self._mixer.update_all() self.request_rebuild_midi_map() #self.log_message('assign_page_0') def assign_page_1(self): with self.component_guard(): self._backlight_type = 'pulse' self._session_zoom.set_enabled(False) for column in range(4): for row in range(4): self._grid[column][row].send_value(DRUM_COLOR[self._rgb], True) self._grid[column + 4][row].send_value(BASS_COLOR[self._rgb], True) self._grid[column][row].set_enabled(False) self._grid[column][row]._msg_channel = PAGE1_DRUM_CHANNEL self._grid[column][row].set_identifier(PAGE1_DRUM_MAP[column][row]) self._grid[column + 4][row].set_enabled(False) self._grid[column + 4][row]._msg_channel = PAGE1_BASS_CHANNEL self._grid[column + 4][row].set_identifier(PAGE1_BASS_MAP[column][row]) scale_mode_buttons = [] for column in range(8): for row in range(3): self._grid[column][row + 4].set_enabled(False) self._grid[column][row + 4].send_value(KEYS_COLOR[self._rgb], True) self._grid[column][row + 4]._msg_channel = PAGE1_KEYS_CHANNEL self._grid[column][row + 4].set_identifier(int(PAGE1_KEYS_MAP[column][row]) + int(PAGE1_MODES_MAP[self._scale_mode._mode_index][column]) + int(self._octave_mode._mode_index * 12)) for row in range(1): scale_mode_buttons.append(self._grid[column][7]) self._scale_mode.set_mode_buttons(tuple(scale_mode_buttons)) self._scale_mode.set_enabled(True) self._octave_mode.set_mode_buttons(tuple([self._menu[5], self._menu[2]])) self._octave_mode.set_enabled(True) for column in range(7): self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column + 8]])) self._mixer.channel_strip(column).set_arm_button(self._button[column]) self._device.set_enabled(True) device_param_controls = [] for index in range(8): device_param_controls.append(self._dial[index]) self._device.set_parameter_controls(tuple(device_param_controls)) self._menu[0]._on_value = PLAY_COLOR[self._rgb] for index in range(4): self._menu[2 + index]._on_value = DEVICE_NAV_COLOR[self._rgb] self._device_navigator.set_enabled(True) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) self.request_rebuild_midi_map() def assign_page_2(self): with self.component_guard(): self._backlight_type = 'up' self._session_zoom.set_enabled(True) for column in range(7): self._grid[column][5]._on_value = MUTE_COLOR[self._rgb] self._mixer.channel_strip(column).set_mute_button(self._grid[column][5]) self._grid[column][6]._on_value = CROSSFADE_ASSIGN_COLOR[self._rgb] self._mixer.channel_strip(column).set_crossfade_toggle(self._grid[column][6]) self._grid[column][7]._msg_channel = 2 self._grid[column][7].set_identifier(column) self._grid[column][7].reset() self._grid[column][7].set_enabled(False) self._grid[column][7].send_value(4, True) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) for row in range(5): self._grid[7][row]._off_value = SCENE_LAUNCH_COLOR[self._rgb] self._scene[row].set_launch_button(self._grid[7][row]) self._grid[7][row].set_force_next_value() self._grid[7][row].turn_off() for column in range(4): self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]])) self._mixer.track_eq(column).set_enabled(True) for column in range(3): self._mixer.channel_strip(column + 4).set_pan_control(self._dial[column + 12]) for index in range(4): self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb] self._session.set_track_bank_buttons(self._menu[4], self._menu[3]) self._session.set_scene_bank_buttons(self._menu[5], self._menu[2]) self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]]) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) #self._mixer.update() self.request_rebuild_midi_map() def assign_mod(self): self.modhandler.set_enabled(True) def assign_translation(self): self._translations.set_enabled(True) def assign_alternate_mappings(self, chan): for column in range(8): for row in range(8): self._grid[column][row].set_channel(chan) for knob in self._dial: knob.set_channel(chan) knob.set_enabled(chan is 0) self.request_rebuild_midi_map() def _update_selected_device(self): if self._device_selection_follows_track_selection is True: self._update_device_selection() def handle_sysex(self, midi_bytes): #self.log_message('sysex: ' + str(midi_bytes)) if len(midi_bytes) > 10: if midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 7]): self.log_message(str('>>>color detected')) self._rgb = 0 for button in self._button: button._color_map = COLOR_MAP for column in self._grid: for button in column: button._color_map = COLOR_MAP elif midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 2]): self.log_message(str('>>>mono detected')) self._rgb = 1 for button in self._button: button._color_map = [127 for index in range(0, 7)] for column in self._grid: for button in column: button._color_map = [127 for index in range(0, 7)] self._assign_session_colors() def to_encoder(self, num, val): rv = int(val * 127) self._device._parameter_controls[num].receive_value(rv) p = self._device._parameter_controls[num]._parameter_to_map_to newval = val * (p.max - p.min) + p.min p.value = newval def _set_tempo_buttons(self, buttons): if self._tempo_buttons != None: self._tempo_buttons[0].remove_value_listener(self._tempo_value) self._tempo_buttons[1].remove_value_listener(self._tempo_value) self._tempo_buttons = buttons if buttons != None: for button in buttons: assert isinstance(button, MonoButtonElement) self._tempo_buttons[0].set_on_off_values(4, 0) self._tempo_buttons[0].add_value_listener(self._tempo_value, True) self._tempo_buttons[1].set_on_off_values(4, 0) self._tempo_buttons[1].add_value_listener(self._tempo_value, True) self._tempo_buttons[0].turn_on() self._tempo_buttons[1].turn_on() def _tempo_value(self, value, sender): if value > 0 and self._tempo_buttons.index(sender) == 0: self.song().tempo = round(min(self.song().tempo + 1, 999)) elif value > 0 and self._tempo_buttons.index(sender) == 1: self.song().tempo = round(max(self.song().tempo - 1, 20)) def generate_strip_string(self, display_string): NUM_CHARS_PER_DISPLAY_STRIP = 12 if not display_string: return ' ' * NUM_CHARS_PER_DISPLAY_STRIP if len(display_string.strip()) > NUM_CHARS_PER_DISPLAY_STRIP - 1 and display_string.endswith('dB') and display_string.find('.') != -1: display_string = display_string[:-2] if len(display_string) > NUM_CHARS_PER_DISPLAY_STRIP - 1: for um in [' ', 'i', 'o', 'u', 'e', 'a']: while len(display_string) > NUM_CHARS_PER_DISPLAY_STRIP - 1 and display_string.rfind(um, 1) != -1: um_pos = display_string.rfind(um, 1) display_string = display_string[:um_pos] + display_string[um_pos + 1:] else: display_string = display_string.center(NUM_CHARS_PER_DISPLAY_STRIP - 1) ret = u'' for i in range(NUM_CHARS_PER_DISPLAY_STRIP - 1): if ord(display_string[i]) > 127 or ord(display_string[i]) < 0: ret += ' ' else: ret += display_string[i] ret += ' ' return ret def notification_to_bridge(self, name, value, sender): if isinstance(sender, tuple([MonoButtonElement, MonoEncoderElement])): self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name))) self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value))) def touched(self): if self._touched is 0: self._monobridge._send('touch', 'on') self.schedule_message(2, self.check_touch) self._touched += 1 def check_touch(self): if self._touched > 5: self._touched = 5 elif self._touched > 0: self._touched -= 1 if self._touched is 0: self._monobridge._send('touch', 'off') else: self.schedule_message(2, self.check_touch) def get_clip_names(self): clip_names = [] for scene in self._session._scenes: for clip_slot in scene._clip_slots: if clip_slot.has_clip() is True: clip_names.append(clip_slot._clip_slot) return clip_slot._clip_slot return clip_names