コード例 #1
0
 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)
コード例 #2
0
ファイル: Cntrlr.py プロジェクト: aumhaa/mod
	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]))
コード例 #3
0
ファイル: DS1.py プロジェクト: gdrdimaio/LiveRemoteScripts
	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)
コード例 #4
0
ファイル: DS1.py プロジェクト: thomasf/LiveRemoteScripts
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()
コード例 #5
0
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
コード例 #6
0
ファイル: Cntrlr.py プロジェクト: aumhaa/mod
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