Esempio n. 1
0
    def _setup_controls(self):
        is_momentary = True
        self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                            CHANNEL, LIVID, 'Livid_Button',
                                            self)

        self._dial = [None for index in range(8)]
        for column in range(8):
            self._dial[column] = [None for index in range(4)]
            for row in range(4):
                self._dial[column][row] = CodecEncoderElement(
                    MIDI_CC_TYPE, CHANNEL, CODE_DIALS[row][column],
                    Live.MidiMap.MapMode.absolute,
                    'Dial_' + str(column) + '_' + str(row),
                    (column + (row * 8)), self)  #CODE_DIALS[row][column]

        self._button = [None for index in range(8)]
        for column in range(8):
            self._button[column] = [None for index in range(4)]
            for row in range(4):
                self._button[column][row] = FlashingButtonElement(
                    is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                    CODE_BUTTONS[row][column],
                    'Button_' + str(column) + '_' + str(row), self)

        self._column_button = [None for index in range(8)]
        for index in range(8):
            self._column_button[index] = FlashingButtonElement(
                is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                CODE_COLUMN_BUTTONS[index], 'Column_Button_' + str(index),
                self)

        self._row_button = [None for index in range(4)]
        for index in range(4):
            self._row_button[index] = FlashingButtonElement(
                is_momentary, MIDI_NOTE_TYPE, CHANNEL, CODE_ROW_BUTTONS[index],
                'Row_Button_' + str(index), self)

        self._dial_matrix = EncoderMatrixElement(self)
        self._dial_matrix.name = 'Encoder_Matrix'
        for row in range(4):
            dial_row = tuple([self._dial[column][row] for column in range(8)])
            self._dial_matrix.add_row(dial_row)

        self._button_matrix = ButtonMatrixElement()
        self._button_matrix.name = 'Button_Matrix'
        for row in range(4):
            button_row = [self._button[column][row] for column in range(8)]
            button_row.append(self._row_button[row])
            self._button_matrix.add_row(tuple(button_row))
        self._button_matrix.add_row(tuple(self._column_button + [self._livid]))
Esempio n. 2
0
    def _setup_controls(self):
        is_momentary = True
        self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, "Livid_Button", self)

        self._dial = [None for index in range(8)]
        for column in range(8):
            self._dial[column] = [None for index in range(4)]
            for row in range(4):
                self._dial[column][row] = CodecEncoderElement(
                    MIDI_CC_TYPE,
                    CHANNEL,
                    CODE_DIALS[row][column],
                    Live.MidiMap.MapMode.absolute,
                    "Dial_" + str(column) + "_" + str(row),
                    (column + (row * 8)),
                    self,
                )  # CODE_DIALS[row][column]

        self._button = [None for index in range(8)]
        for column in range(8):
            self._button[column] = [None for index in range(4)]
            for row in range(4):
                self._button[column][row] = FlashingButtonElement(
                    is_momentary,
                    MIDI_NOTE_TYPE,
                    CHANNEL,
                    CODE_BUTTONS[row][column],
                    "Button_" + str(column) + "_" + str(row),
                    self,
                )

        self._column_button = [None for index in range(8)]
        for index in range(8):
            self._column_button[index] = FlashingButtonElement(
                is_momentary, MIDI_NOTE_TYPE, CHANNEL, CODE_COLUMN_BUTTONS[index], "Column_Button_" + str(index), self
            )

        self._row_button = [None for index in range(4)]
        for index in range(4):
            self._row_button[index] = FlashingButtonElement(
                is_momentary, MIDI_NOTE_TYPE, CHANNEL, CODE_ROW_BUTTONS[index], "Row_Button_" + str(index), self
            )

        self._dial_matrix = EncoderMatrixElement(self)
        self._dial_matrix.name = "Encoder_Matrix"
        for row in range(4):
            dial_row = tuple([self._dial[column][row] for column in range(8)])
            self._dial_matrix.add_row(dial_row)

        self._button_matrix = ButtonMatrixElement()
        self._button_matrix.name = "Button_Matrix"
        for row in range(4):
            button_row = [self._button[column][row] for column in range(8)]
            button_row.append(self._row_button[row])
            self._button_matrix.add_row(tuple(button_row))
        self._button_matrix.add_row(tuple(self._column_button + [self._livid]))
Esempio n. 3
0
class Codec(ControlSurface):
    __module__ = __name__
    __doc__ = " MonoCode controller script "

    def __init__(self, c_instance):
        """everything except the '_on_selected_track_CHANNELged' override and 'disconnect' runs from here"""
        ControlSurface.__init__(self, c_instance)
        self.set_suppress_rebuild_requests(
            True
        )  # Turn off rebuild MIDI map until after we're done setting up
        self._monomod_version = 'b995'
        self._version_check = 'b995'
        self._host_name = 'Codec'
        self._color_type = 'Monochrome'
        self._link_mixer = LINK_MIXER
        self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Codec ' +
                         str(self._monomod_version) +
                         ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
        self._hosts = []
        self._linked_script = None
        self._local_ring_control = True
        self.set_local_ring_control(1)
        self._setup_controls()
        self._last_device = None
        self._device_list = [None, None, None, None]
        self._device_select_buttons = None
        self._last_device_component = None
        self._timer = 0
        self._touched = 0
        self._locked = False
        self.flash_status = 1
        self._shift_button = None
        self._shift_pressed = 0
        self._shift_pressed_timer = 0
        self._shift_thresh = SHIFT_THRESH
        self._use_device_selector = USE_DEVICE_SELECTOR
        self._device_selection_follows_track_selection = FOLLOW
        self.set_suppress_rebuild_requests(
            False)  #Turn rebuild back on, now that we're done setting up
        self.song().view.add_selected_track_listener(
            self._update_selected_device)
        self.show_message('Codec Control Surface Loaded')
        #self.local_ring_control(True)
        #self.set_absolute_mode(True)
        self._setup_monobridge()
        self._setup_device_controls()
        self._setup_special_device_control()
        self._device.append(
            self._special_device
        )  #necessary for device browsing to work with special device
        self._setup_device_chooser()
        self._setup_mixer_controls()
        self._setup_monomod()
        self._setup_modes()
        self._setup_device_selector()
        self._setup_send_reset()
        self._setup_default_buttons()
        self._initialize_code()
        self.request_rebuild_midi_map()
        #Monomodular.create_instance(c_instance)
        #self._setup_disconnect()

    """script initialization methods"""

    def _initialize_code(self):
        self._send_midi(factoryreset)
        self._send_midi(btn_channels)
        self._send_midi(enc_channels)
        #pass

    def _setup_monobridge(self):
        self._monobridge = MonoBridgeElement(self)
        self._monobridge.name = 'MonoBridge'

    def _setup_controls(self):
        is_momentary = True
        self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                            CHANNEL, LIVID, 'Livid_Button',
                                            self)

        self._dial = [None for index in range(8)]
        for column in range(8):
            self._dial[column] = [None for index in range(4)]
            for row in range(4):
                self._dial[column][row] = CodecEncoderElement(
                    MIDI_CC_TYPE, CHANNEL, CODE_DIALS[row][column],
                    Live.MidiMap.MapMode.absolute,
                    'Dial_' + str(column) + '_' + str(row),
                    (column + (row * 8)), self)  #CODE_DIALS[row][column]

        self._button = [None for index in range(8)]
        for column in range(8):
            self._button[column] = [None for index in range(4)]
            for row in range(4):
                self._button[column][row] = FlashingButtonElement(
                    is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                    CODE_BUTTONS[row][column],
                    'Button_' + str(column) + '_' + str(row), self)

        self._column_button = [None for index in range(8)]
        for index in range(8):
            self._column_button[index] = FlashingButtonElement(
                is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                CODE_COLUMN_BUTTONS[index], 'Column_Button_' + str(index),
                self)

        self._row_button = [None for index in range(4)]
        for index in range(4):
            self._row_button[index] = FlashingButtonElement(
                is_momentary, MIDI_NOTE_TYPE, CHANNEL, CODE_ROW_BUTTONS[index],
                'Row_Button_' + str(index), self)

        self._dial_matrix = EncoderMatrixElement(self)
        self._dial_matrix.name = 'Encoder_Matrix'
        for row in range(4):
            dial_row = tuple([self._dial[column][row] for column in range(8)])
            self._dial_matrix.add_row(dial_row)

        self._button_matrix = ButtonMatrixElement()
        self._button_matrix.name = 'Button_Matrix'
        for row in range(4):
            button_row = [self._button[column][row] for column in range(8)]
            button_row.append(self._row_button[row])
            self._button_matrix.add_row(tuple(button_row))
        self._button_matrix.add_row(tuple(self._column_button + [self._livid]))

    def _setup_modes(self):
        self._monomod_mode = MonomodModeComponent(self)
        self._monomod_mode.name = 'Monomod_Mode'
        self._monomod_mode.update = self._mod_mode_update
        #self._monomod_mode.set_mode_toggle(self._livid)
        self.set_shift_button(self._livid)
        self._shift_mode = ShiftModeComponent(self, self._shift_update)
        self._shift_mode.name = 'Shift_Mode'
        self._shift_mode.set_mode_buttons(
            tuple([
                self._row_button[0], self._row_button[1], self._row_button[2],
                self._row_button[3]
            ]))

    def _setup_transport_control(self):
        self._transport = TransportComponent()
        self._transport.name = 'Transport'

    def _setup_monomod(self):
        self._host = MonomodComponent(self)
        self._host.name = 'Monomod_Host'
        self._host._set_dial_matrix(self._dial_matrix, self._button_matrix)
        self.hosts = [self._host]
        encs = []
        for row in range(4):
            for col in range(8):
                encs.append(self._dial[col][row])
        self._host._set_parameter_controls(encs)

    def _setup_mixer_controls(self):
        is_momentary = True
        self._num_tracks = (8)
        self._session = SessionComponent(self._num_tracks, 0)
        self._session.name = 'Session'
        self._mixer = MixerComponent(self._num_tracks, 0, False, False)
        self._mixer.name = 'Mixer'
        self._mixer._next_track_value = self._mixer_next_track_value(
            self._mixer)
        self._mixer._prev_track_value = self._mixer_prev_track_value(
            self._mixer)
        self._mixer.set_track_offset(
            0)  #Sets start point for mixer strip (offset from left)
        #for index in range(8):
        #use the bottom row of encoders for volume, so add 24 to offset the index
        #	self._mixer.channel_strip(index).set_volume_control(self._dial[index+24])
        for index in range(8):
            self._mixer.channel_strip(
                index).name = 'Mixer_ChannelStrip_' + str(index)
            self._mixer.channel_strip(index)._invert_mute_feedback = True
            self._mixer.channel_strip(
                index)._mute_value = self._channelstrip_mute_value(
                    self._mixer.channel_strip(index))
            self._mixer.channel_strip(
                index)._solo_value = self._channelstrip_solo_value(
                    self._mixer.channel_strip(index))
            #mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, track_select_notes[index]))
        self.song().view.selected_track = self._mixer.channel_strip(
            0
        )._track  #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
        self._session.set_mixer(self._mixer)

    def _setup_device_controls(self):
        self._device = [None for index in range(4)]
        for index in range(4):
            self._device[index] = CodecDeviceComponent(self)
            self._device[index].name = 'CodecDevice_Component_' + str(index)
            device_param_controls = []
            for control in range(8):
                device_param_controls.append(self._dial[control][index])
            self._device[index].set_on_off_button(self._button[1][index])
            self._device[index].set_lock_button(self._button[2][index])
            self._device[index].set_bank_nav_buttons(self._button[4][index],
                                                     self._button[5][index])
            self._device[index].set_nav_buttons(self._button[6][index],
                                                self._button[7][index])
            self._device[index].set_parameter_controls(
                tuple(device_param_controls))
        self.set_device_component(self._device[0])
        self._last_device_component = self._device[0]

    def _setup_special_device_control(self):
        self._special_device = SpecialCodecDeviceComponent(self)
        self._special_device.name = 'SpecialCodecDeviceComponent'
        self._special_device.set_on_off_button(self._button[1][0])
        self._special_device.set_lock_button(self._button[2][0])
        self._special_device.set_bank_nav_buttons(self._button[4][0],
                                                  self._button[5][0])
        self._special_device.set_nav_buttons(self._button[6][0],
                                             self._button[7][0])
        device_param_controls = []
        for row in range(4):
            for column in range(8):
                device_param_controls.append(self._dial[column][row])
        self._special_device.set_parameter_controls(
            tuple(device_param_controls))

    def _setup_device_chooser(self):
        self._selected_device = self._device[0]
        self._last_selected_device = self._device[0]
        self._device_select_buttons = [
            self._button[0][index] for index in range(4)
        ]
        for button in self._device_select_buttons:
            button.add_value_listener(self._device_select_value, True)

    def _setup_device_selector(self):
        self._device_selector = CodecDeviceSelectorComponent(
            self, 'c', self._device + [self._special_device])
        self._device_selector.name = 'Device_Selector'
        self._device_selector.set_mode_buttons(self._column_button)
        #self._device_selector.set_mode_toggle(self._livid)

    def _setup_send_reset(self):
        self._send_reset = CodecResetSendsComponent(self)
        self._send_reset.set_buttons(self._button)

    def _setup_default_buttons(self):
        self._value_default = ParameterDefaultComponent(self)
        buttons = []
        dials = []
        for column in self._button:
            for button in column:
                buttons.append(button)
        for column in self._dial:
            for dial in column:
                dials.append(dial)
        self._value_default.set_buttons(buttons)
        self._value_default.set_dials(dials)

    """multiple device support"""

    def _device_select_value(self, value, sender):
        #self.log_message('device_select_value ' + str(value) + ' ' + str(self._device_select_buttons.index(sender)))
        if not self._shift_pressed:
            if sender.is_momentary or value > 0:
                if self._shift_mode._mode_index == 2:
                    self.set_device_component(self._device[
                        self._device_select_buttons.index(sender)])
                    self._last_device_component = self._device_component
                    if self._device_component != None and isinstance(
                            self._device_component._device,
                            Live.Device.Device):
                        if self._device_component.find_track(
                                self._device_component._device) == self.song(
                                ).view.selected_track:
                            self._device_component.display_device()

    """livid double press mechanism"""

    def set_shift_button(self, button):
        assert ((button == None)
                or (isinstance(button, FlashingButtonElement)))
        if self._shift_button != None:
            self._shift_button.remove_value_listener(self._shift_value)
        self._shift_button = button
        if self._shift_button != None:
            self._shift_button.add_value_listener(self._shift_value)

    def _shift_value(self, value):
        self._shift_pressed = int(value != 0)
        if self._shift_pressed > 0:
            self._send_midi(SLOWENCODER)
            if (self._shift_pressed_timer + self._shift_thresh) > self._timer:
                #if(self._host.is_enabled() != True)
                self._monomod_mode.set_mode(
                    abs(self._monomod_mode._mode_index - 1))
                #else:
                #	self._monomod_mode.set_mode(0)
            self._shift_pressed_timer = self._timer % 256
        else:
            self._send_midi(NORMALENCODER)

    def _mod_mode_update(self):
        if (self._monomod_mode._mode_index == 0):
            self._host._set_shift_button(None)
            self._host.set_enabled(False)
            self._dial_matrix.reset()
            self._shift_mode.set_enabled(True)
            self._shift_update()
            self.request_rebuild_midi_map()
            self._livid.turn_off()
        elif (self._monomod_mode._mode_index == 1):
            self._shift_mode.set_enabled(False)
            self._deassign_all()
            self._dial_matrix.reset()
            self._button_matrix.reset()
            self._livid.turn_on()
            if not self._host._active_client == None:
                self._host.set_enabled(True)
                self._host._set_shift_button(self._livid)
            else:
                self._assign_alternate_mappings(1)
            self.request_rebuild_midi_map()

    """Mode Functions"""

    def _shift_update(self):
        if (self._shift_mode.is_enabled()):
            self.allow_updates(False)
            if (not self._in_build_midi_map):
                self.set_suppress_rebuild_requests(True)
            self._deassign_all()
            if (self._shift_mode._mode_index is 0):
                self._assign_volume()
            elif (self._shift_mode._mode_index is 1):
                self._assign_sends()
            elif (self._shift_mode._mode_index is 2):
                self._assign_devices()
            elif (self._shift_mode._mode_index is 3):
                self._assign_special_device()
            for index in range(self._shift_mode.number_of_modes()):
                if index == self._shift_mode._mode_index:
                    self._shift_mode._modes_buttons[index].turn_on()
                else:
                    self._shift_mode._modes_buttons[index].turn_off()
            self.allow_updates(True)
            self.set_suppress_rebuild_requests(False)
            self.request_rebuild_midi_map()

    def _deassign_all(self):
        self._assign_alternate_mappings(0)
        self._device_selector.set_enabled(False)
        for index in range(8):
            self._mixer.channel_strip(index).set_volume_control(None)
            self._mixer.channel_strip(index).set_pan_control(None)
            self._mixer.channel_strip(index).set_send_controls(
                tuple([None, None, None, None]))
        for index in range(4):
            self._device[index].set_enabled(False)
            self._device[index]._parameter_controls = None
            #self._device_navigator[index].set_enabled(False)
        self._special_device.set_enabled(False)
        self._special_device._parameter_controls = None
        self._device_selector.set_enabled(False)
        self._deassign_buttons()
        for control in self.controls:
            control.reset()
        self.request_rebuild_midi_map()

    def _deassign_buttons(self):
        for index in range(8):
            self._mixer.channel_strip(index).set_select_button(None)
            self._mixer.channel_strip(index).set_solo_button(None)
            self._mixer.channel_strip(index).set_mute_button(None)
        self._mixer.set_select_buttons(None, None)
        self._send_reset.set_enabled(False)

    def _assign_volume(self):
        for index in range(8):
            self._mixer.channel_strip(index).set_volume_control(
                self._dial[index][3])
            self._mixer.channel_strip(index).set_pan_control(
                self._dial[index][2])
            self._mixer.channel_strip(index).set_send_controls(
                tuple([self._dial[index][0], self._dial[index][1]]))
            self._mixer.channel_strip(index).set_select_button(
                self._column_button[index])
            self._mixer.channel_strip(index).set_solo_button(
                self._button[index][2])
            self._mixer.channel_strip(index).set_mute_button(
                self._button[index][3])
        self._mixer.set_select_buttons(self._button[7][0], self._button[6][0])

    def _assign_sends(self):
        for index in range(8):
            self._mixer.channel_strip(index).set_send_controls(
                tuple([
                    self._dial[index][0], self._dial[index][1],
                    self._dial[index][2], self._dial[index][3]
                ]))
            self._mixer.channel_strip(index).set_select_button(
                self._column_button[index])
            self._send_reset.set_enabled(True)

    def _assign_devices(self):
        self.set_device_component(self._last_device_component)
        self._device_select_value(
            1, self._device_select_buttons[self._device.index(
                self._device_component)])
        for index in range(4):
            device_param_controls = []
            for control in range(8):
                device_param_controls.append(self._dial[control][index])
            self._device[index].set_parameter_controls(
                tuple(device_param_controls))
            self._device[index].set_enabled(True)
        self._device_selector.set_enabled(self._use_device_selector)
        if not self._use_device_selector:
            for index in range(8):
                self._mixer.channel_strip(index).set_select_button(
                    self._column_button[index])

    def _assign_special_device(self):
        self.set_device_component(self._special_device)
        device_param_controls = []
        for row in range(4):
            for column in range(8):
                device_param_controls.append(self._dial[column][row])
        self._special_device.set_parameter_controls(
            tuple(device_param_controls))
        self._special_device.set_enabled(True)
        self._device_selector.set_enabled(self._use_device_selector)
        if not self._use_device_selector:
            for index in range(8):
                self._mixer.channel_strip(index).set_select_button(
                    self._column_button[index])

    def _assign_alternate_mappings(self, chan):
        for column in self._dial:
            for control in column:
                control.set_channel(chan)
                control.set_enabled(chan is 0)
        for column in self._button:
            for control in column:
                control.set_channel(chan)
                control.set_enabled(chan is 0)
        for control in self._column_button:
            control.set_channel(chan)
            control.set_enabled(chan is 0)
        for control in self._row_button:
            control.set_channel(chan)
            control.set_enabled(chan is 0)

    """general functionality"""

    def disconnect(self):
        """clean things up on disconnect"""
        if not self._shift_button is None:
            if self._shift_button.value_has_listener(self._shift_value):
                self._shift_button.remove_value_listener(self._shift_value)
        for button in self._device_select_buttons:
            if button.value_has_listener(self._device_select_value):
                button.remove_value_listener(self._device_select_value)
        if self._session._is_linked():
            self._session._unlink()
        self.song().view.remove_selected_track_listener(
            self._update_selected_device)
        """for cs in self._control_surfaces():
			for host in self._hosts:
				self.log_message('installed: ' + str(cs) + ' vs. ' + str(host))
				if str(type(cs)) == str(type(host)):
					self.log_message('disconnecting: ' + str(type(cs)))
					cs.disconnect(cs)"""
        #self._host._set_parameter_controls(None)
        self._hosts = []
        if self._linked_script != None:
            self._linked_script._update_linked_device_selection = None
        self._linked_script = None
        #self._disconnect_notifier.set_mode(0)
        self.log_message(
            '<<<<<<<<<<<<<<<<<<<<<<<<< Codec log closed >>>>>>>>>>>>>>>>>>>>>>>>>'
        )
        ControlSurface.disconnect(self)
        return None

    def connect_script_instances(self, instanciated_scripts):
        found = False
        for s in instanciated_scripts:
            if '_codec_version' in dir(s):
                if s._codec_version == self._version_check:
                    if s._host_name == ('MonOhm'):
                        self.log_message('found codec version ' +
                                         str(s._codec_version) +
                                         ' in script ' + str(s._host_name))
                        found = True
                        self._linked_script = s
                        self._linked_script._update_linked_device_selection = self._update_linked_device_selection
                        if not self._session._is_linked(
                        ) and self._link_mixer is True:
                            self._session.set_offsets(LINK_OFFSET[0],
                                                      LINK_OFFSET[1])
                            self._session._link()
                else:
                    self.log_message('version mismatch: Monomod version ' +
                                     str(self._version_check) +
                                     ' vs. Host version ' +
                                     str(s._codec_version))

        if found == False:
            for s in instanciated_scripts:
                if '_codec_version' in dir(s):
                    if s._codec_version == self._version_check:
                        if s._host_name == 'BlockMod':
                            self.log_message('found codec version ' +
                                             str(s._codec_version) +
                                             ' in script ' + str(s._host_name))
                            self._linked_script = s
                            self._linked_script._update_linked_device_selection = self._update_linked_device_selection
                        if not self._session._is_linked(
                        ) and self._link_mixer is True:
                            self._session.set_offsets(LINK_OFFSET[0],
                                                      LINK_OFFSET[1])
                            self._session._link()
                    else:
                        self.log_message('version mismatch: Monomod version ' +
                                         str(self._version_check) +
                                         ' vs. Host version ' +
                                         str(s._codec_version))
        #self.log_message('hosts: ' + str(self._hosts))"""

    def update_display(self):
        ControlSurface.update_display(
            self
        )  #since we are overriding this from the inherited method, we need to call the original routine as well
        self._timer = (self._timer + 1) % 256
        if (self._timer == 0):
            self._shift_pressed_timer = -12
        if (self._local_ring_control is False):
            self.send_ring_leds()
        self.flash()

    def handle_sysex(self, midi_bytes):
        #self._send_midi(tuple([240, 00, 01, 97, 04, 15, 01, 247]))
        #response = [long(0),long(0)]
        #self.log_message(response)
        pass

    def flash(self):
        if (self.flash_status > 0):
            for control in self.controls:
                if isinstance(control, FlashingButtonElement):
                    control.flash(self._timer)

    def send_ring_leds(self):
        leds = [240, 0, 1, 97, 4, 31]
        for column in range(8):
            for row in range(4):
                wheel = self._dial[column][row]
                bytes = wheel._get_ring()
                leds.append(bytes[0])
                leds.append(int(bytes[1]) + int(bytes[2]))
                #if(row == 1 and column == 0):
                #	self.log_message(str(leds) + ' ' + str(bytes[0]) + ' ' + str(bytes[1]) + ' ' + str(bytes[2]))
        leds.append(247)
        self._send_midi(tuple(leds))

    def set_absolute_mode(self, val=1):
        self._absolute_mode = (val != 0)
        if self._absolute_mode is True:
            self._send_midi(
                tuple([240, 0, 1, 97, 4, 17, 0, 0, 0, 0, 0, 0, 0, 0, 247]))
        else:
            self._send_midi(
                tuple([
                    240, 0, 1, 97, 4, 17, 127, 127, 127, 127, 127, 127, 127,
                    127, 247
                ]))

    def set_local_ring_control(self, val=1):
        self._local_ring_control = (val != 0)
        if (self._local_ring_control is True):
            #self._send_midi(tuple([240, 0, 1, 97, 4, 32, 0, 247]))
            self._send_midi(tuple([240, 0, 1, 97, 4, 8, 72, 247]))
        else:
            #self._send_midi(tuple([240, 0, 1, 97, 4, 32, 1, 247]))
            self._send_midi(tuple([240, 0, 1, 97, 4, 8, 64, 247]))

    def device_follows_track(self, val):
        self._device_selection_follows_track_selection = (val == 1)
        return self

    """m4l 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 += ' '
        assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
        return ret

    def notification_to_bridge(self, name, value, sender):
        if (isinstance(sender, CodecEncoderElement)):
            self._monobridge._send(sender.name, 'lcd_name',
                                   str(self.generate_strip_string(name)))
            self._monobridge._send(sender.name, 'lcd_value',
                                   str(self.generate_strip_string(value)))

    def touched(self):
        if not self._host.is_enabled():
            if self._touched is 0:
                self._monobridge._send('touch', 'on')
                self.schedule_message(2, self.check_touch)
            self._touched += 1

    def check_touch(self):
        if self._touched > 5:
            self._touched = 5
        elif self._touched > 0:
            self._touched -= 1
        if self._touched is 0:
            self._monobridge._send('touch', 'off')
        else:
            self.schedule_message(2, self.check_touch)

    def get_clip_names(self):
        clip_names = []
        for scene in self._session._scenes:
            for clip_slot in scene._clip_slots:
                if clip_slot.has_clip() is True:
                    clip_names.append(clip_slot._clip_slot)  ##.clip.name)
                    return clip_slot._clip_slot
                    ##self.log_message(str(clip_slot._clip_slot.clip.name))
        return clip_names

    """overrides"""

    def allow_updates(self, allow_updates):
        for component in self.components:
            component.set_allow_update(int(allow_updates != 0))

    def set_device_component(self, device_component):
        if self._device_component != None:
            self._device_component._lock_callback = None
        assert (device_component != None)
        assert isinstance(device_component, DeviceComponent)
        self._device_component = device_component
        self._device_component._lock_callback = self._toggle_lock  #old:  self._device_component.set_lock_callback(self._toggle_lock)
        if self._device_select_buttons != None:
            for button in self._device_select_buttons:
                button.send_value(
                    self._device_select_buttons.index(button) ==
                    self._device.index(self._device_component))
        self._update_device_selection()
        return None

    def _update_selected_device(self):
        if self._device_selection_follows_track_selection is True:
            self._update_device_selection()
        return None

    def _update_linked_device_selection(self, device):
        #self.log_message('codec received ' + str(device.name))
        if self._device_component != None and device != None:
            if not self._device_component.is_locked():
                self._device_component.set_device(device)

    def _get_num_tracks(self):
        return self.num_tracks

    def _update_device_selection(self):  #new method: code to verify
        #self.log_message('_update_device_selection')
        if self._device_component != None:
            if not self._device_component.is_locked():
                track = self.song().view.selected_track
                device_to_select = track.view.selected_device
                if ((device_to_select == None) and (len(track.devices) > 0)):
                    device_to_select = track.devices[0]
                if (device_to_select != None):
                    self.song().view.select_device(device_to_select)
                self._device_component.set_device(device_to_select)

    def _channelstrip_mute_value(self, channelstrip):
        def _mute_value(value):
            if not self._shift_pressed:
                self.log_message('shift not pressed')
                ChannelStripComponent._mute_value(channelstrip, value)

        return _mute_value

    def _channelstrip_solo_value(self, channelstrip):
        def _solo_value(value):
            if not self._shift_pressed:
                ChannelStripComponent._solo_value(channelstrip, value)

        return _solo_value

    def _mixer_next_track_value(self, mixer):
        def _next_track_value(value):
            if not self._shift_pressed:
                MixerComponent._next_track_value(mixer, value)

        return _next_track_value

    def _mixer_prev_track_value(self, mixer):
        def _prev_track_value(value):
            if not self._shift_pressed:
                MixerComponent._prev_track_value(mixer, value)

        return _prev_track_value
Esempio n. 4
0
class OhmModes(ControlSurface):
	__module__ = __name__
	__doc__ = ' OhmModes controller script '

	def __init__(self, c_instance):
		ControlSurface.__init__(self, c_instance)
		with self.component_guard():
			self._version_check = 'b994'
			self._host_name = 'Ohm'
			self._color_type = 'OhmRGB'
			self._hosts = []
			self.hosts = []
			self._client = [ None for index in range(6) ]
			self._active_client = None
			self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< OhmModes ' + str(self._version_check) + ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
			self._rgb = 0
			self._timer = 0
			self._touched = 0
			self.flash_status = 1
			self._backlight = 127
			self._backlight_type = 'static'
			self._ohm = 127
			self._ohm_type = 'static'
			self._pad_translations = PAD_TRANSLATION
			self._device_selection_follows_track_selection = FOLLOW
			self._keys_octave = 5
			self._keys_scale = 0
			self._tempo_buttons = None
			self._setup_monobridge()
			self._setup_controls()
			self._setup_transport_control()
			self._setup_mixer_control()
			self._setup_session_control()
			self._setup_device_control()
			self._setup_crossfader()
			self._setup_ohmmod()
			self._setup_switchboard()
			self._setup_modes()
			self._assign_page_constants()
			self._last_device = None
			self.song().view.add_selected_track_listener(self._update_selected_device)
			self.show_message('OhmModes Control Surface Loaded')
			self._send_midi(tuple(switchxfader))
			if FORCE_TYPE is True:
				self._rgb = FORCE_COLOR_TYPE
			else:
				self.schedule_message(10, self.query_ohm, None)
			self.log_message(str(self._highlighting_session_component))

	def query_ohm(self):
		self._send_midi(tuple(check_model))

	def update_display(self):
		ControlSurface.update_display(self)
		self._timer = (self._timer + 1) % 256
		self.flash()
		self.strobe()

	def _setup_monobridge(self):
		self._monobridge = MonoBridgeElement(self)
		self._monobridge.name = 'MonoBridge'

	def get_device_bank(self):
		return self._device._bank_index

	def _setup_controls(self):
		is_momentary = True
		self._fader = [ None for index in range(8) ]
		self._dial = [ None for index in range(16) ]
		self._button = [ None for index in range(8) ]
		self._menu = [ None for index in range(6) ]
		for index in range(8):
			self._fader[index] = MonoEncoderElement2(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self)

		for index in range(8):
			self._button[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self)

		for index in range(16):
			self._dial[index] = CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), index, self)

		self._knobs = []
		for index in range(12):
			self._knobs.append(self._dial[index])

		for index in range(6):
			self._menu[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self)

		self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute)
		self._crossfader.name = 'Crossfader'
		self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		self._shift_l = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Page_Button_Left', self)
		self._shift_r = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Page_Button_Right', self)
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		self._grid = [ None for index in range(8) ]
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		for column in range(8):
			self._grid[column] = [ None for index in range(8) ]
			for row in range(8):
				self._grid[column][row] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, column * 8 + row, 'Grid_' + str(column) + '_' + str(row), self)

		for row in range(5):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])

			self._matrix.add_row(tuple(button_row))

		for row in range(8):
			button_row = []
			for column in range(8):
				button_row.append(self._grid[column][row])

			self._monomod.add_row(tuple(button_row))

		self._mod_matrix = ButtonMatrixElement()
		self._mod_matrix.name = 'Matrix'
		self._dial_matrix = EncoderMatrixElement(self)
		self._dial_matrix.name = 'Dial_Matrix'
		self._dial_button_matrix = ButtonMatrixElement()
		self._dial_button_matrix.name = 'Dial_Button_Matrix'
		for row in range(4):
			button_row = []
			for column in range(4):
				button_row.append(self._grid[column + 4][row])

			self._mod_matrix.add_row(tuple(button_row))

		for row in range(3):
			dial_row = []
			for column in range(4):
				dial_row.append(self._dial[row * 4 + column])

			self._dial_matrix.add_row(tuple(dial_row))

		for row in range(3):
			dial_button_row = []
			for column in range(4):
				dial_button_row.append(self._grid[column][row])

			self._dial_button_matrix.add_row(tuple(dial_button_row))

		self._key = [ self._grid[KEYS[index][1]][KEYS[index][0]] for index in range(32) ]
		self._encoder = [ self._dial[index] for index in range(12) ]
		self._key_matrix = ButtonMatrixElement()
		button_row = []
		for column in range(16):
			button_row.append(self._key[16 + column])

		self._key_matrix.add_row(tuple(button_row))

	def _setup_ohmmod(self):
		self._host = MonomodComponent(self)
		self._host.name = 'Monomod_Host'
		self.hosts = [self._host]
		self._hosts = [self._host]
		for index in range(6):
			self._client[index] = MonoClient(self, index)
			self._client[index].name = 'Client_' + str(index)
			self._client[index]._device_component.set_parameter_controls(tuple([ self._dial[num] for num in range(12) ]))
			self._client[index]._control_defs = {'dials': self._dial_matrix,
			 'buttons': self._dial_button_matrix,
			 'grid': self._mod_matrix,
			 'keys': self._key,
			 'knobs': [ self._dial[num + 12] for num in range(4) ]}

		self._host._active_client = self._client[0]
		self._host._active_client._is_active = True
		self._host.connect_to_clients(self)

	def _setup_switchboard(self):
		self._switchboard = SwitchboardElement(self, self._client)
		self._switchboard.name = 'Switchboard'

	def _setup_modes(self):
		self._shift_mode = ShiftModeComponent(self)
		self._shift_mode.name = 'Shift_Mode'
		self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r, self._livid)
		self._scale_mode = ScaleModeComponent(self)
		self._scale_mode.name = 'Scale_Mode'
		self._octave_mode = OctaveModeComponent(self)
		self._octave_mode.name = 'Octave_Mode'
		self._modNum = ModNumModeComponent(self, self.modNum_update)
		self._modNum.name = 'Mod_Number'
		self._modNum.set_mode = self._modNum_set_mode(self._modNum)
		self._modNum.set_mode_buttons([ self._menu[index] for index in range(6) ])

	def _modNum_set_mode(self, modNum):
		def set_mode(mode):
			if modNum._is_enabled == True:
				assert isinstance(mode, int)
				assert (mode in range(modNum.number_of_modes()))
				if (modNum._mode_index != mode):
					modNum._mode_index = mode
					modNum.update()
		return set_mode
	

	def _setup_transport_control(self):
		self._transport = TransportComponent()
		self._transport.name = 'Transport'

	def _setup_mixer_control(self):
		global mixer
		is_momentary = True
		self._num_tracks = 7
		mixer = SpecialMixerComponent(7, 0, True, False)
		mixer.name = 'Mixer'
		self._mixer = mixer
		for index in range(7):
			mixer.channel_strip(index).set_volume_control(self._fader[index])

		for index in range(7):
			mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			mixer.track_eq(index).name = 'Mixer_EQ_' + str(index)
			mixer.channel_strip(index)._invert_mute_feedback = True

		self.song().view.selected_track = mixer.channel_strip(0)._track

	def _setup_session_control(self):
		global session
		is_momentary = True
		num_tracks = 7
		num_scenes = 5
		session = SessionComponent(num_tracks, num_scenes)
		session.name = 'Session'
		self._session = session
		session.set_offsets(0, 0)
		self._scene = [ None for index in range(6) ]
		for row in range(num_scenes):
			self._scene[row] = session.scene(row)
			self._scene[row].name = 'Scene_' + str(row)
			for column in range(num_tracks):
				clip_slot = self._scene[row].clip_slot(column)
				clip_slot.name = str(column) + '_Clip_Slot_' + str(row)

		session.set_mixer(self._mixer)
		session.set_show_highlight(True)
		self._session_zoom = SessionZoomingComponent(session)
		self._session_zoom.name = 'Session_Overview'
		self.set_highlighting_session_component(self._session)

	def _assign_session_colors(self):
		self.log_message('assign session colors')
		num_tracks = 7
		num_scenes = 5
		self._session.set_stop_track_clip_value(STOP_CLIP_COLOR[self._rgb])
		for row in range(num_scenes):
			for column in range(num_tracks):
				self._scene[row].clip_slot(column).set_triggered_to_play_value(CLIP_TRIGD_TO_PLAY_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_triggered_to_record_value(CLIP_TRIGD_TO_RECORD_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_stopped_value(CLIP_STOPPED_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_recording_value(CLIP_RECORDING_COLOR[self._rgb])

		self._session_zoom.set_stopped_value(ZOOM_STOPPED_COLOR[self._rgb])
		self._session_zoom.set_playing_value(ZOOM_PLAYING_COLOR[self._rgb])
		self._session_zoom.set_selected_value(ZOOM_SELECTED_COLOR[self._rgb])
		for row in range(8):
			for column in range(8):
				self._grid[column][row].set_force_next_value()

		self._session.on_scene_list_changed()
		self._shift_mode.update()

	def _setup_device_control(self):
		self._device = DeviceComponent()
		self._device.name = 'Device_Component'
		self.set_device_component(self._device)
		self._device_navigator = DetailViewControllerComponent()
		self._device_navigator.name = 'Device_Navigator'
		self._device_selection_follows_track_selection = FOLLOW

	def device_follows_track(self, val):
		self._device_selection_follows_track_selection = val == 1
		return self

	def _setup_crossfader(self):
		self._mixer.set_crossfader_control(self._crossfader)

	def disconnect(self):
		"""clean things up on disconnect"""
		self.song().view.remove_selected_track_listener(self._update_selected_device)
		self.log_message(time.strftime('%d.%m.%Y %H:%M:%S', time.localtime()) + '--------------= OhmModes log closed =--------------')
		ControlSurface.disconnect(self)

	def _get_num_tracks(self):
		return self.num_tracks

	def flash(self):
		for row in range(8):
			if self._button[row]._flash_state > 0:
				self._button[row].flash(self._timer)
			for column in range(8):
				button = self._grid[column][row]
				if button._flash_state > 0:
					button.flash(self._timer)

	def strobe(self):
		if self._backlight_type != 'static':
			if self._backlight_type is 'pulse':
				self._backlight = int(math.fabs(self._timer * 16 % 64 - 32) + 32)
			if self._backlight_type is 'up':
				self._backlight = int(self._timer * 8 % 64 + 16)
			if self._backlight_type is 'down':
				self._backlight = int(math.fabs(int(self._timer * 8 % 64 - 64)) + 16)
		self._send_midi(tuple([176, 27, int(self._backlight)]))
		if self._ohm_type != 'static':
			if self._ohm_type is 'pulse':
				self._ohm = int(math.fabs(self._timer * 16 % 64 - 32) + 32)
			if self._ohm_type is 'up':
				self._ohm = int(self._timer * 8 % 64 + 16)
			if self._ohm_type is 'down':
				self._ohm = int(math.fabs(int(self._timer * 8 % 64 - 64)) + 16)
		self._send_midi(tuple([176, 63, int(self._ohm)]))
		self._send_midi(tuple([176, 31, int(self._ohm)]))

	def deassign_matrix(self):
		with self.component_guard():
			self._host._set_knobs(None)
			self._host._set_button_matrix(None)
			self._host.set_enabled(False)
			self._modNum.set_enabled(False)
			self.assign_alternate_mappings(0)
			self._scale_mode.set_mode_buttons(None)
			self._scale_mode.set_enabled(False)
			self._octave_mode.set_mode_buttons(None)
			self._octave_mode.set_enabled(False)
			self._session_zoom.set_enabled(False)
			self._session_zoom.set_nav_buttons(None, None, None, None)
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)
			self._transport.set_enabled(False)
			for column in range(4):
				self._mixer.track_eq(column)._gain_controls = None
				self._mixer.track_eq(column).set_enabled(False)

			for column in range(7):
				self._mixer.channel_strip(column).set_crossfade_toggle(None)
				self._mixer.channel_strip(column).set_mute_button(None)
				self._mixer.channel_strip(column).set_solo_button(None)
				self._mixer.channel_strip(column).set_arm_button(None)
				self._mixer.channel_strip(column).set_send_controls(None)
				self._mixer.channel_strip(column).set_pan_control(None)
				self._mixer.track_eq(column).set_enabled(False)
				for row in range(5):
					self._scene[row].clip_slot(column).set_launch_button(None)

			"""for column in range(8):
				self._button[column]._on_value = SELECT_COLOR[self._rgb]
				for row in range(8):
					self._grid[column][row].set_enabled(True)
					self._grid[column][row].release_parameter()
					self._grid[column][row].use_default_message()
					self._grid[column][row].set_on_off_values(127, 0)
					self._grid[column][row].send_value(0, True)"""
			for column in range(8):
				self._button[column]._on_value = SELECT_COLOR[self._rgb]
				for row in range(8):
					#self._grid[column][row].set_channel(0)
					self._grid[column][row].release_parameter()
					self._grid[column][row].use_default_message()
					self._grid[column][row].set_enabled(True)
					self._grid[column][row].send_value(0, True)
					self._grid[column][row]._on_value = 127
					self._grid[column][row]._off_value = 0
					self._grid[column][row].force_next_send()


			for index in range(6):
				self._menu[index]._on_value = 127
				self._menu[index]._off_value = 0

			for index in range(16):
				self._dial[index].use_default_message()
				self._dial[index].release_parameter()

			self._device.set_parameter_controls(None)
			self._device.set_enabled(False)
			self._device_navigator.set_enabled(False)
			self._mixer.update()
			self._matrix.reset()
		self.request_rebuild_midi_map()

	def _assign_page_constants(self):
		with self.component_guard():
			self._session_zoom.set_zoom_button(self._grid[7][7])
			self._session_zoom.set_button_matrix(self._matrix)
			for column in range(7):
				self._mixer.channel_strip(column).set_select_button(self._button[column])
				self._mixer.channel_strip(column).set_volume_control(self._fader[column])

			self._mixer.master_strip().set_volume_control(self._fader[7])
			self._mixer.master_strip().set_select_button(self._button[7])
			self._mixer.set_prehear_volume_control(self._dial[15])
			self._transport.set_play_button(self._menu[0])
			self._menu[0].send_value(PLAY_COLOR[self._rgb], True)
			self._menu[0]._on_value = PLAY_COLOR[self._rgb]
			self._transport.set_stop_button(self._menu[1])
			self._menu[1]._off_value = STOP_COLOR[self._rgb]
			self._menu[1]._on_value = STOP_COLOR[self._rgb]
			self._menu[1].send_value(STOP_COLOR[self._rgb], True)
			self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[4])

	def assign_page_0(self):
		with self.component_guard():
			self._backlight_type = 'static'
			self._session_zoom.set_enabled(True)
			for column in range(7):	
				self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
				self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
				self._grid[column][6]._on_value = SOLO_COLOR[self._rgb]
				self._mixer.channel_strip(column).set_solo_button(self._grid[column][6])
				self._grid[column][7]._on_value = ARM_COLOR[self._rgb]
				self._mixer.channel_strip(column).set_arm_button(self._grid[column][7])
				self._mixer.channel_strip(column).set_pan_control(self._dial[column + 8])
				for row in range(5):
					self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])

			for column in range(4):
				self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column], self._dial[column + 4]]))

			for index in range(5):
				self._grid[7][index]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
				self._scene[index].set_launch_button(self._grid[7][index])
				self._grid[7][index].set_force_next_value()
				self._grid[7][index].turn_off()

			for index in range(4):
				self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]

			self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
			self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])
			self._menu[0]._on_value = PLAY_COLOR[self._rgb]
			self._menu[1]._off_value = STOP_COLOR[self._rgb]
			self._menu[1]._on_value = STOP_COLOR[self._rgb]
			self._transport.set_enabled(True)
			#self._mixer.update_all()
		self.request_rebuild_midi_map()
		#self.log_message('assign_page_0')

	def assign_page_1(self):
		with self.component_guard():
			self._backlight_type = 'pulse'
			self._session_zoom.set_enabled(False)
			for column in range(4):
				for row in range(4):
					self._grid[column][row].send_value(DRUM_COLOR[self._rgb], True)
					self._grid[column + 4][row].send_value(BASS_COLOR[self._rgb], True)
					self._grid[column][row].set_enabled(False)
					self._grid[column][row]._msg_channel = PAGE1_DRUM_CHANNEL
					self._grid[column][row].set_identifier(PAGE1_DRUM_MAP[column][row])
					self._grid[column + 4][row].set_enabled(False)
					self._grid[column + 4][row]._msg_channel = PAGE1_BASS_CHANNEL
					self._grid[column + 4][row].set_identifier(PAGE1_BASS_MAP[column][row])

			scale_mode_buttons = []
			for column in range(8):
				for row in range(3):
					self._grid[column][row + 4].set_enabled(False)
					self._grid[column][row + 4].send_value(KEYS_COLOR[self._rgb], True)
					self._grid[column][row + 4]._msg_channel = PAGE1_KEYS_CHANNEL
					self._grid[column][row + 4].set_identifier(int(PAGE1_KEYS_MAP[column][row]) + int(PAGE1_MODES_MAP[self._scale_mode._mode_index][column]) + int(self._octave_mode._mode_index * 12))

				for row in range(1):
					scale_mode_buttons.append(self._grid[column][7])

			self._scale_mode.set_mode_buttons(tuple(scale_mode_buttons))
			self._scale_mode.set_enabled(True)
			self._octave_mode.set_mode_buttons(tuple([self._menu[5], self._menu[2]]))
			self._octave_mode.set_enabled(True)
			for column in range(7):
				self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column + 8]]))
				self._mixer.channel_strip(column).set_arm_button(self._button[column])

			self._device.set_enabled(True)
			device_param_controls = []
			for index in range(8):
				device_param_controls.append(self._dial[index])

			self._device.set_parameter_controls(tuple(device_param_controls))
			self._menu[0]._on_value = PLAY_COLOR[self._rgb]
			for index in range(4):
				self._menu[2 + index]._on_value = DEVICE_NAV_COLOR[self._rgb]

			self._device_navigator.set_enabled(True)
			self._menu[0]._on_value = PLAY_COLOR[self._rgb]
			self._menu[1]._off_value = STOP_COLOR[self._rgb]
			self._menu[1]._on_value = STOP_COLOR[self._rgb]
			self._transport.set_enabled(True)
		self.request_rebuild_midi_map()

	def assign_page_2(self):
		with self.component_guard():
			self._backlight_type = 'up'
			self._session_zoom.set_enabled(True)
			for column in range(7):
				self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
				self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
				self._grid[column][6]._on_value = CROSSFADE_ASSIGN_COLOR[self._rgb]
				self._mixer.channel_strip(column).set_crossfade_toggle(self._grid[column][6])
				self._grid[column][7]._msg_channel = 2
				self._grid[column][7].set_identifier(column)
				self._grid[column][7].reset()
				self._grid[column][7].set_enabled(False)
				self._grid[column][7].send_value(4, True)
				for row in range(5):
					self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])

			for row in range(5):
				self._grid[7][row]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
				self._scene[row].set_launch_button(self._grid[7][row])
				self._grid[7][row].set_force_next_value()
				self._grid[7][row].turn_off()

			for column in range(4):
				self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]]))
				self._mixer.track_eq(column).set_enabled(True)

			for column in range(3):
				self._mixer.channel_strip(column + 4).set_pan_control(self._dial[column + 12])

			for index in range(4):
				self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]

			self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
			self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])
			self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]])
			self._menu[0]._on_value = PLAY_COLOR[self._rgb]
			self._menu[1]._off_value = STOP_COLOR[self._rgb]
			self._menu[1]._on_value = STOP_COLOR[self._rgb]
			self._transport.set_enabled(True)
			#self._mixer.update()
		self.request_rebuild_midi_map()

	def assign_mod(self):
		with self.component_guard():
			self.deassign_matrix()
			self._host.set_enabled(True)
			self._modNum.set_enabled(True)
			self._host._set_dial_matrix(self._dial_matrix, self._dial_button_matrix)
			self._host._set_button_matrix(self._mod_matrix)
			self._host._set_key_buttons(tuple(self._key))
			if not self._host._active_client.is_connected():
				self.assign_alternate_mappings(self._modNum._mode_index + 1)

	def modNum_update(self):
		if self._modNum._is_enabled == True:
			self.assign_alternate_mappings(0)
			self._host._select_client(int(self._modNum._mode_index))
			self._host.display_active_client()
			if not self._host._active_client.is_connected():
				self.assign_alternate_mappings(self._modNum._mode_index + 1)
			for button in self._modNum._modes_buttons:
				if self._modNum._mode_index == self._modNum._modes_buttons.index(button):
					button.send_value(1)
				else:
					button.send_value(self._client[self._modNum._modes_buttons.index(button)]._mod_color)

	def assign_alternate_mappings(self, chan):
		for column in range(8):
			for row in range(8):
				self._grid[column][row].set_channel(chan)
		for knob in self._encoder:
			knob.set_channel(chan)
			knob.set_enabled(chan is 0)

		self.request_rebuild_midi_map()

	def display_mod_colors(self):
		pass

	def _update_selected_device(self):
		if self._device_selection_follows_track_selection is True:
			track = self.song().view.selected_track
			device_to_select = track.view.selected_device
			if device_to_select == None and len(track.devices) > 0:
				device_to_select = track.devices[0]
			if device_to_select != None:
				self.song().view.select_device(device_to_select)
			self.set_appointed_device(device_to_select)
			self.request_rebuild_midi_map()

	def handle_sysex(self, midi_bytes):
		if len(midi_bytes) > 10:
			if midi_bytes[:11] == tuple([240,
			 126,
			 0,
			 6,
			 2,
			 0,
			 1,
			 97,
			 1,
			 0,
			 7]):
				self.log_message(str('>>>color detected'))
				self._rgb = 0
			elif midi_bytes[:11] == tuple([240,
			 126,
			 0,
			 6,
			 2,
			 0,
			 1,
			 97,
			 1,
			 0,
			 2]):
				self.log_message(str('>>>mono detected'))
				self._rgb = 1
		self._assign_session_colors()

	def to_encoder(self, num, val):
		rv = int(val * 127)
		self._device._parameter_controls[num].receive_value(rv)
		p = self._device._parameter_controls[num]._parameter_to_map_to
		newval = val * (p.max - p.min) + p.min
		p.value = newval

	def set_local_ring_control(self, val = 1):
		self._local_ring_control = val != 0

	def set_absolute_mode(self, val = 1):
		self._absolute_mode = val != 0

	def send_ring_leds(self):
		"""if self._host._is_enabled == True:
		leds = [240, 0, 1, 97, 8, 31]
		for index in range(12):
				wheel = self._encoder[index]
				bytes = wheel._get_ring()
				leds.append(bytes[0])
				leds.append(int(bytes[1]) + int(bytes[2]))
		leds.append(247)
		self._send_midi(tuple(leds))"""
		pass


	def _set_tempo_buttons(self, buttons):
		if self._tempo_buttons != None:
			self._tempo_buttons[0].remove_value_listener(self._tempo_value)
			self._tempo_buttons[1].remove_value_listener(self._tempo_value)
		self._tempo_buttons = buttons
		if buttons != None:
			for button in buttons:
				 assert isinstance(button, FlashingButtonElement)
			self._tempo_buttons[0].set_on_off_values(4, 0)
			self._tempo_buttons[0].add_value_listener(self._tempo_value, True)
			self._tempo_buttons[1].set_on_off_values(4, 0)
			self._tempo_buttons[1].add_value_listener(self._tempo_value, True)
			self._tempo_buttons[0].turn_on()
			self._tempo_buttons[1].turn_on()

	def _tempo_value(self, value, sender):
		if value > 0 and self._tempo_buttons.index(sender) == 0:
			self.song().tempo = round(min(self.song().tempo + 1, 999))
		elif value > 0 and self._tempo_buttons.index(sender) == 1:
			self.song().tempo = round(max(self.song().tempo - 1, 20))

	def generate_strip_string(self, display_string):
		NUM_CHARS_PER_DISPLAY_STRIP = 12
		if not display_string:
			return ' ' * NUM_CHARS_PER_DISPLAY_STRIP
		if len(display_string.strip()) > NUM_CHARS_PER_DISPLAY_STRIP - 1 and display_string.endswith('dB') and display_string.find('.') != -1:
			display_string = display_string[:-2]
		if len(display_string) > NUM_CHARS_PER_DISPLAY_STRIP - 1:
			for um in [' ',
			 'i',
			 'o',
			 'u',
			 'e',
			 'a']:
				while len(display_string) > NUM_CHARS_PER_DISPLAY_STRIP - 1 and display_string.rfind(um, 1) != -1:
					um_pos = display_string.rfind(um, 1)
					display_string = display_string[:um_pos] + display_string[um_pos + 1:]

		else:
			display_string = display_string.center(NUM_CHARS_PER_DISPLAY_STRIP - 1)
		ret = u''
		for i in range(NUM_CHARS_PER_DISPLAY_STRIP - 1):
			if ord(display_string[i]) > 127 or ord(display_string[i]) < 0:
				ret += ' '
			else:
				ret += display_string[i]

		ret += ' '
		return ret

	def notification_to_bridge(self, name, value, sender):
		if isinstance(sender, tuple([MonoEncoderElement2, CodecEncoderElement])):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))

	def touched(self):
		if self._touched is 0:
			self._monobridge._send('touch', 'on')
			self.schedule_message(2, self.check_touch)
		self._touched += 1

	def check_touch(self):
		if self._touched > 5:
			self._touched = 5
		elif self._touched > 0:
			self._touched -= 1
		if self._touched is 0:
			self._monobridge._send('touch', 'off')
		else:
			self.schedule_message(2, self.check_touch)

	def get_clip_names(self):
		clip_names = []
		for scene in self._session._scenes:
			for clip_slot in scene._clip_slots:
				if clip_slot.has_clip() is True:
					clip_names.append(clip_slot._clip_slot)
					return clip_slot._clip_slot

		return clip_names

	def shift_update(self):
		pass
Esempio n. 5
0
	def _setup_controls(self):
		is_momentary = True
		self._fader = [ None for index in range(8) ]
		self._dial = [ None for index in range(16) ]
		self._button = [ None for index in range(8) ]
		self._menu = [ None for index in range(6) ]
		for index in range(8):
			self._fader[index] = MonoEncoderElement2(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self)

		for index in range(8):
			self._button[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self)

		for index in range(16):
			self._dial[index] = CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), index, self)

		self._knobs = []
		for index in range(12):
			self._knobs.append(self._dial[index])

		for index in range(6):
			self._menu[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self)

		self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute)
		self._crossfader.name = 'Crossfader'
		self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		self._shift_l = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Page_Button_Left', self)
		self._shift_r = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Page_Button_Right', self)
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		self._grid = [ None for index in range(8) ]
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		for column in range(8):
			self._grid[column] = [ None for index in range(8) ]
			for row in range(8):
				self._grid[column][row] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, column * 8 + row, 'Grid_' + str(column) + '_' + str(row), self)

		for row in range(5):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])

			self._matrix.add_row(tuple(button_row))

		for row in range(8):
			button_row = []
			for column in range(8):
				button_row.append(self._grid[column][row])

			self._monomod.add_row(tuple(button_row))

		self._mod_matrix = ButtonMatrixElement()
		self._mod_matrix.name = 'Matrix'
		self._dial_matrix = EncoderMatrixElement(self)
		self._dial_matrix.name = 'Dial_Matrix'
		self._dial_button_matrix = ButtonMatrixElement()
		self._dial_button_matrix.name = 'Dial_Button_Matrix'
		for row in range(4):
			button_row = []
			for column in range(4):
				button_row.append(self._grid[column + 4][row])

			self._mod_matrix.add_row(tuple(button_row))

		for row in range(3):
			dial_row = []
			for column in range(4):
				dial_row.append(self._dial[row * 4 + column])

			self._dial_matrix.add_row(tuple(dial_row))

		for row in range(3):
			dial_button_row = []
			for column in range(4):
				dial_button_row.append(self._grid[column][row])

			self._dial_button_matrix.add_row(tuple(dial_button_row))

		self._key = [ self._grid[KEYS[index][1]][KEYS[index][0]] for index in range(32) ]
		self._encoder = [ self._dial[index] for index in range(12) ]
		self._key_matrix = ButtonMatrixElement()
		button_row = []
		for column in range(16):
			button_row.append(self._key[16 + column])

		self._key_matrix.add_row(tuple(button_row))
Esempio n. 6
0
class Codec(ControlSurface):
	__module__ = __name__
	__doc__ = " MonoCode controller script "


	def __init__(self, c_instance):
		"""everything except the '_on_selected_track_CHANNELged' override and 'disconnect' runs from here"""
		ControlSurface.__init__(self, c_instance)
		self.set_suppress_rebuild_requests(True) # Turn off rebuild MIDI map until after we're done setting up
		self._monomod_version = 'b994'
		self._version_check = 'b994'
		self._host_name = 'Codec'
		self._color_type = 'Monochrome'
		self._link_mixer = LINK_MIXER
		self.log_message("--------------= Codec " + str(self._monomod_version) + " log opened =--------------") 
		self._hosts = []
		self._linked_script = None
		self._local_ring_control = True
		self.set_local_ring_control(1)
		self._setup_controls()
		self._last_device = None
		self._device_list = [None, None, None, None]
		self._device_select_buttons = None
		self._last_device_component = None
		self._timer = 0
		self._touched = 0
		self._locked = False
		self.flash_status = 1
		self._shift_button = None
		self._shift_pressed = 0
		self._shift_pressed_timer = 0
		self._shift_thresh = SHIFT_THRESH
		self._use_device_selector = USE_DEVICE_SELECTOR
		self._device_selection_follows_track_selection=FOLLOW
		self.set_suppress_rebuild_requests(False) #Turn rebuild back on, now that we're done setting up
		self.song().view.add_selected_track_listener(self._update_selected_device)
		self.show_message('Codec Control Surface Loaded')
		#self.local_ring_control(True)
		#self.set_absolute_mode(True)
		self._setup_monobridge()
		self._setup_device_controls()
		self._setup_special_device_control() 
		self._device.append(self._special_device)			#necessary for device browsing to work with special device
		self._setup_device_chooser()
		self._setup_mixer_controls()
		self._setup_monomod()
		self._setup_modes() 
		self._setup_device_selector()
		self._setup_send_reset()
		self._setup_default_buttons()
		self._initialize_code()
		self.request_rebuild_midi_map()
		#Monomodular.create_instance(c_instance)
		#self._setup_disconnect()
	


	"""script initialization methods"""
	def _initialize_code(self):
		self._send_midi(factoryreset)
		self._send_midi(btn_channels)
		self._send_midi(enc_channels)	
		#pass
	

	def _setup_monobridge(self):
		self._monobridge = MonoBridgeElement(self)
		self._monobridge.name = 'MonoBridge'
	

	def _setup_controls(self):
		is_momentary = True
		self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)

		self._dial = [None for index in range(8)]
		for column in range(8):
			self._dial[column] = [None for index in range(4)]
			for row in range(4):
				self._dial[column][row] = CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, CODE_DIALS[row][column], Live.MidiMap.MapMode.absolute, 'Dial_' + str(column) + '_' +	str(row), (column + (row*8)), self)	#CODE_DIALS[row][column]
		
		self._button = [None for index in range(8)]
		for column in range(8):
			self._button[column] = [None for index in range(4)]
			for row in range(4):
				self._button[column][row] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CODE_BUTTONS[row][column], 'Button_' + str(column) + '_' + str(row), self) 
		

		self._column_button = [None for index in range(8)]
		for index in range(8):
			self._column_button[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CODE_COLUMN_BUTTONS[index], 'Column_Button_' + str(index), self)		
			
		self._row_button = [None for index in range(4)]
		for index in range(4):
			self._row_button[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CODE_ROW_BUTTONS[index], 'Row_Button_' + str(index), self)		

		self._dial_matrix = EncoderMatrixElement(self)
		self._dial_matrix.name = 'Encoder_Matrix'
		for row in range(4):
			dial_row = tuple([self._dial[column][row] for column in range(8)])
			self._dial_matrix.add_row(dial_row)

		self._button_matrix = ButtonMatrixElement()
		self._button_matrix.name = 'Button_Matrix'
		for row in range(4):
			button_row = [self._button[column][row] for column in range(8)]
			button_row.append(self._row_button[row])
			self._button_matrix.add_row(tuple(button_row))
		self._button_matrix.add_row(tuple(self._column_button + [self._livid]))
	

	def _setup_modes(self):
		self._monomod_mode = MonomodModeComponent(self)
		self._monomod_mode.name = 'Monomod_Mode'
		self._monomod_mode.update = self._mod_mode_update
		#self._monomod_mode.set_mode_toggle(self._livid)
		self.set_shift_button(self._livid)
		self._shift_mode = ShiftModeComponent(self, self._shift_update) 
		self._shift_mode.name = 'Shift_Mode'
		self._shift_mode.set_mode_buttons(tuple([self._row_button[0], self._row_button[1], self._row_button[2], self._row_button[3]]))
	

	def _setup_transport_control(self):
		self._transport = TransportComponent() 
		self._transport.name = 'Transport'
	

	def _setup_monomod(self):
		self._host = MonomodComponent(self)
		self._host.name = 'Monomod_Host'
		self._host._set_dial_matrix(self._dial_matrix, self._button_matrix)
		#self._host._set_shift_button(self._row_button[3])
		self.hosts = [self._host]
		#self._host._set_button_matrix(self._button_matrix)
		#for index
		#self._host._set_shift
	

	def _setup_mixer_controls(self):
		is_momentary = True
		self._num_tracks = (8)
		self._session = SessionComponent(self._num_tracks, 0)
		self._session.name = 'Session'
		self._mixer = MixerComponent(self._num_tracks, 0, False, False)
		self._mixer.name = 'Mixer'
		self._mixer._next_track_value = self._mixer_next_track_value(self._mixer)
		self._mixer._prev_track_value = self._mixer_prev_track_value(self._mixer)
		self._mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		#for index in range(8):
			#use the bottom row of encoders for volume, so add 24 to offset the index
		#	self._mixer.channel_strip(index).set_volume_control(self._dial[index+24])
		for index in range(8):
			self._mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			self._mixer.channel_strip(index)._invert_mute_feedback = True
			self._mixer.channel_strip(index)._mute_value = self._channelstrip_mute_value(self._mixer.channel_strip(index))
			self._mixer.channel_strip(index)._solo_value = self._channelstrip_solo_value(self._mixer.channel_strip(index))
			#mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, track_select_notes[index]))
		self.song().view.selected_track = self._mixer.channel_strip(0)._track #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
		self._session.set_mixer(self._mixer)
	

	def _setup_device_controls(self):
		self._device = [None for index in range(4)]
		for index in range(4):
			self._device[index] = CodecDeviceComponent(self)
			self._device[index].name = 'CodecDevice_Component_' + str(index)
			device_param_controls = []
			for control in range(8):
				device_param_controls.append(self._dial[control][index])
			self._device[index].set_on_off_button(self._button[1][index])
			self._device[index].set_lock_button(self._button[2][index])
			self._device[index].set_bank_nav_buttons(self._button[4][index], self._button[5][index])
			self._device[index].set_nav_buttons(self._button[6][index], self._button[7][index])
			self._device[index].set_parameter_controls(tuple(device_param_controls))
		self.set_device_component(self._device[0])
		self._last_device_component = self._device[0]
	

	def _setup_special_device_control(self):
		self._special_device = SpecialCodecDeviceComponent(self)
		self._special_device.name = 'SpecialCodecDeviceComponent'
		self._special_device.set_on_off_button(self._button[1][0])
		self._special_device.set_lock_button(self._button[2][0])
		self._special_device.set_bank_nav_buttons(self._button[4][0], self._button[5][0])
		self._special_device.set_nav_buttons(self._button[6][0], self._button[7][0])
		device_param_controls = []
		for row in range(4):
			for column in range(8):
				device_param_controls.append(self._dial[column][row])
		self._special_device.set_parameter_controls(tuple(device_param_controls))
	

	def _setup_device_chooser(self):
		self._selected_device = self._device[0]
		self._last_selected_device = self._device[0]
		self._device_select_buttons = [self._button[0][index] for index in range(4)]
		for button in self._device_select_buttons:
			button.add_value_listener(self._device_select_value, True)
	
	
	def _setup_device_selector(self):
		self._device_selector = CodecDeviceSelectorComponent(self, 'c', self._device + [self._special_device])
		self._device_selector.name = 'Device_Selector'
		self._device_selector.set_mode_buttons(self._column_button)
		#self._device_selector.set_mode_toggle(self._livid)
	

	def _setup_send_reset(self):
		self._send_reset = CodecResetSendsComponent(self)
		self._send_reset.set_buttons(self._button)
	

	def _setup_default_buttons(self):
		self._value_default = ParameterDefaultComponent(self)
		buttons = []
		dials = []
		for column in self._button:
			for button in column:
				buttons.append(button)
		for column in self._dial:
			for dial in column:
				dials.append(dial)
		self._value_default.set_buttons(buttons)
		self._value_default.set_dials(dials)
	


	"""multiple device support"""
	def _device_select_value(self, value, sender):
		#self.log_message('device_select_value ' + str(value) + ' ' + str(self._device_select_buttons.index(sender)))
		if not self._shift_pressed:
			if sender.is_momentary or value > 0:
				if self._shift_mode._mode_index == 2:
					self.set_device_component(self._device[self._device_select_buttons.index(sender)])
					self._last_device_component = self._device_component
					if self._device_component != None and isinstance(self._device_component._device, Live.Device.Device):
						if self._device_component.find_track(self._device_component._device) == self.song().view.selected_track:
							self._device_component.display_device()
	


	"""livid double press mechanism"""
	def set_shift_button(self, button):
		assert ((button == None) or (isinstance(button, FlashingButtonElement)))
		if self._shift_button != None:
			self._shift_button.remove_value_listener(self._shift_value)
		self._shift_button = button
		if self._shift_button != None:
			self._shift_button.add_value_listener(self._shift_value)
	

	def _shift_value(self, value):
		self._shift_pressed = int(value != 0)
		if self._shift_pressed > 0:
			self._send_midi(SLOWENCODER)
			if (self._shift_pressed_timer + self._shift_thresh) > self._timer:
				#if(self._host.is_enabled() != True)
				self._monomod_mode.set_mode(abs(self._monomod_mode._mode_index - 1))
				#else:
				#	self._monomod_mode.set_mode(0)
			self._shift_pressed_timer = self._timer % 256
		else:
			self._send_midi(NORMALENCODER)
	

	def _mod_mode_update(self):
		if(self._monomod_mode._mode_index == 0):
			self._host._set_shift_button(None)
			self._host.set_enabled(False)
			self.set_local_ring_control(1)
			self.set_absolute_mode(1)
			self._dial_matrix.reset()
			self._shift_mode.set_enabled(True)
			self._shift_update()
			self.request_rebuild_midi_map()
			self._livid.turn_off()
		elif(self._monomod_mode._mode_index == 1):
			self._shift_mode.set_enabled(False)
			self._deassign_all()
			self._dial_matrix.reset()
			self._button_matrix.reset()			
			self._livid.turn_on()
			if not self._host._active_client == None:
				self.set_local_ring_control(0)
				self.set_absolute_mode(0)
				self._host.set_enabled(True)
				self._host._set_shift_button(self._livid)
			else:
				self.set_local_ring_control(1)
				self.set_absolute_mode(1)
				self._assign_alternate_mappings(1)
			self.request_rebuild_midi_map()
	


	"""Mode Functions"""
	def _shift_update(self):
		if(self._shift_mode.is_enabled()):
			self.allow_updates(False)
			if(not self._in_build_midi_map):
				self.set_suppress_rebuild_requests(True)
			self._deassign_all()
			if(self._shift_mode._mode_index is 0):
				self._assign_volume()
			elif(self._shift_mode._mode_index is 1):
				self._assign_sends()
			elif(self._shift_mode._mode_index is 2):
				self._assign_devices()
			elif(self._shift_mode._mode_index is 3):
				self._assign_special_device()
			for index in range(self._shift_mode.number_of_modes()):
				if index == self._shift_mode._mode_index:
					self._shift_mode._modes_buttons[index].turn_on()
				else:
					self._shift_mode._modes_buttons[index].turn_off()
			self.allow_updates(True)
			self.set_suppress_rebuild_requests(False)
			self.request_rebuild_midi_map()
	

	def _deassign_all(self):
		self._assign_alternate_mappings(0)
		self._device_selector.set_enabled(False)
		for index in range(8):
			self._mixer.channel_strip(index).set_volume_control(None)
			self._mixer.channel_strip(index).set_pan_control(None)
			self._mixer.channel_strip(index).set_send_controls(tuple([None, None, None, None]))
		for index in range(4):
			self._device[index].set_enabled(False)
			#self._device_navigator[index].set_enabled(False)
		self._special_device.set_enabled(False)
		self._device_selector.set_enabled(False)
		self._deassign_buttons()
		for control in self.controls:
			control.reset()
		self.request_rebuild_midi_map()
	

	def _deassign_buttons(self):
		for index in range(8):
			self._mixer.channel_strip(index).set_select_button(None)
			self._mixer.channel_strip(index).set_solo_button(None)
			self._mixer.channel_strip(index).set_mute_button(None)
		self._mixer.set_select_buttons(None, None)
		self._send_reset.set_enabled(False)
	

	def _assign_volume(self):
		for index in range(8):
			self._mixer.channel_strip(index).set_volume_control(self._dial[index][3])
			self._mixer.channel_strip(index).set_pan_control(self._dial[index][2])
			self._mixer.channel_strip(index).set_send_controls(tuple([self._dial[index][0], self._dial[index][1]]))
			self._mixer.channel_strip(index).set_select_button(self._column_button[index])
			self._mixer.channel_strip(index).set_solo_button(self._button[index][2])
			self._mixer.channel_strip(index).set_mute_button(self._button[index][3])
		self._mixer.set_select_buttons(self._button[7][0], self._button[6][0])
	

	def _assign_sends(self):
		for index in range(8):
			self._mixer.channel_strip(index).set_send_controls(tuple([self._dial[index][0], self._dial[index][1], self._dial[index][2], self._dial[index][3]]))
			self._mixer.channel_strip(index).set_select_button(self._column_button[index])
			self._send_reset.set_enabled(True)
	

	def _assign_devices(self):
		self.set_device_component(self._last_device_component)
		self._device_select_value(1, self._device_select_buttons[self._device.index(self._device_component)])
		for index in range(4):
			self._device[index].set_enabled(True)
		self._device_selector.set_enabled(self._use_device_selector)
		if not self._use_device_selector:
			for index in range(8):
				self._mixer.channel_strip(index).set_select_button(self._column_button[index])				
	

	def _assign_special_device(self):
		self.set_device_component(self._special_device)
		self._special_device.set_enabled(True)
		self._device_selector.set_enabled(self._use_device_selector)
		if not self._use_device_selector:
			for index in range(8):
				self._mixer.channel_strip(index).set_select_button(self._column_button[index])	
	

	def _assign_alternate_mappings(self, chan):
		for column in self._dial:
			for control in column:
				control.set_channel(chan)
				control.set_enabled(chan is 0)
		for column in self._button:
			for control in column:
				control.set_channel(chan)
				control.set_enabled(chan is 0)
		for control in self._column_button:
			control.set_channel(chan)
			control.set_enabled(chan is 0)
		for control in self._row_button:
			control.set_channel(chan)
			control.set_enabled(chan is 0)
	


	"""general functionality"""
	def disconnect(self):
		"""clean things up on disconnect"""
		if not self._shift_button is None:
			if self._shift_button.value_has_listener(self._shift_value):
				self._shift_button.remove_value_listener(self._shift_value)
		for button in self._device_select_buttons:
			if button.value_has_listener(self._device_select_value):
				button.remove_value_listener(self._device_select_value)
		if self._session._is_linked():
			self._session._unlink()
		self.song().view.remove_selected_track_listener(self._update_selected_device)
		"""for cs in self._control_surfaces():
			for host in self._hosts:
				self.log_message('installed: ' + str(cs) + ' vs. ' + str(host))
				if str(type(cs)) == str(type(host)):
					self.log_message('disconnecting: ' + str(type(cs)))
					cs.disconnect(cs)"""
		self._hosts = []
		if self._linked_script != None:
			self._linked_script._update_linked_device_selection = None
		self._linked_script = None
		#self._disconnect_notifier.set_mode(0)
		self.log_message("--------------= Codec log closed =--------------") #Create entry in log file
		ControlSurface.disconnect(self)
		return None
		
	

	def connect_script_instances(self, instanciated_scripts):
		found = False
		for s in instanciated_scripts:
			if '_codec_version' in dir(s):
				if s._codec_version == self._version_check:
					if s._host_name == ('MonOhm'):
						self.log_message('found codec version ' + str(s._codec_version) + ' in script ' + str(s._host_name))
						found = True
						self._linked_script = s
						self._linked_script._update_linked_device_selection = self._update_linked_device_selection
						if not self._session._is_linked() and self._link_mixer is True:
							self._session.set_offsets(LINK_OFFSET[0], LINK_OFFSET[1])
							self._session._link()
				else:
					self.log_message('version mismatch: Monomod version ' + str(self._version_check) + ' vs. Host version ' + str(s._codec_version))
					

		if found == False:
			for s in instanciated_scripts:
				if '_codec_version' in dir(s):
					if s._codec_version == self._version_check:
						if s._host_name == 'BlockMod':
							self.log_message('found codec version ' + str(s._codec_version) + ' in script ' + str(s._host_name))
							self._linked_script = s
							self._linked_script._update_linked_device_selection = self._update_linked_device_selection
						if not self._session._is_linked() and self._link_mixer is True:
							self._session.set_offsets(LINK_OFFSET[0], LINK_OFFSET[1])
							self._session._link()
					else:
						self.log_message('version mismatch: Monomod version ' + str(self._version_check) + ' vs. Host version ' + str(s._codec_version))
		#self.log_message('hosts: ' + str(self._hosts))"""
	

	def update_display(self):
		ControlSurface.update_display(self)		#since we are overriding this from the inherited method, we need to call the original routine as well
		self._timer = (self._timer + 1) % 256
		if(self._timer == 0):
			self._shift_pressed_timer = -12
		if(self._local_ring_control is False):
			self.send_ring_leds()
		self.flash()
	

	def handle_sysex(self, midi_bytes):
		#self._send_midi(tuple([240, 00, 01, 97, 04, 15, 01, 247]))
		#response = [long(0),long(0)]
		#self.log_message(response)
		pass
	

	def flash(self):
		if(self.flash_status > 0):
			for control in self.controls:
				if isinstance(control, FlashingButtonElement):
					control.flash(self._timer)
	

	def send_ring_leds(self):
		leds = [240, 0, 1, 97, 4, 31]
		for column in range(8):
			for row in range(4):
				wheel = self._dial[column][row]
				bytes = wheel._get_ring()
				leds.append(bytes[0])
				leds.append(int(bytes[1]) + int(bytes[2]))
				#if(row == 1 and column == 0):
				#	self.log_message(str(leds) + ' ' + str(bytes[0]) + ' ' + str(bytes[1]) + ' ' + str(bytes[2]))
		leds.append(247)
		self._send_midi(tuple(leds))
	

	def set_absolute_mode(self, val = 1):
		self._absolute_mode = (val!=0)
		if self._absolute_mode is True:
			self._send_midi(tuple([240, 0, 1, 97, 4, 17, 0, 0, 0, 0, 0, 0, 0, 0, 247]))
		else:
			self._send_midi(tuple([240, 0, 1, 97, 4, 17, 127, 127, 127, 127, 127, 127, 127, 127, 247]))
	

	def set_local_ring_control(self, val = 1):
		#assert val is isinstance(val, type(False))
		self._local_ring_control = (val!=0)
		if(self._local_ring_control is True):
			#self._send_midi(tuple([240, 0, 1, 97, 4, 32, 0, 247]))
			self._send_midi(tuple([240, 0, 1, 97, 4, 8, 72, 247]))
		else:
			#self._send_midi(tuple([240, 0, 1, 97, 4, 32, 1, 247]))
			self._send_midi(tuple([240, 0, 1, 97, 4, 8, 64, 247]))
	

	def device_follows_track(self, val):
		self._device_selection_follows_track_selection = (val == 1)
		return self
	


	"""m4l 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 += ' '
		assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
		return ret
	

	def notification_to_bridge(self, name, value, sender):
		if(isinstance(sender, CodecEncoderElement)):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))
	

	def touched(self):
		if not self._host.is_enabled():
			if self._touched is 0:
				self._monobridge._send('touch', 'on')
				self.schedule_message(2, self.check_touch)
			self._touched +=1
	

	def check_touch(self):
		if self._touched > 5:
			self._touched = 5
		elif self._touched > 0:
			self._touched -= 1
		if self._touched is 0:
			self._monobridge._send('touch', 'off')
		else:
			self.schedule_message(2, self.check_touch)
	

	def get_clip_names(self):
		clip_names = []
		for scene in self._session._scenes:
			for clip_slot in scene._clip_slots:
				if clip_slot.has_clip() is True:
					clip_names.append(clip_slot._clip_slot)##.clip.name)
					return clip_slot._clip_slot
					##self.log_message(str(clip_slot._clip_slot.clip.name))
		return clip_names
	


	"""overrides"""
	def allow_updates(self, allow_updates):
		for component in self.components:
			component.set_allow_update(int(allow_updates!=0))
	

	def set_device_component(self, device_component):
		if self._device_component != None:
			self._device_component._lock_callback = None
		assert (device_component != None)
		assert isinstance(device_component, DeviceComponent)
		self._device_component = device_component
		self._device_component._lock_callback = self._toggle_lock	#old:  self._device_component.set_lock_callback(self._toggle_lock)
		if self._device_select_buttons != None:
			for button in self._device_select_buttons:
				button.send_value(self._device_select_buttons.index(button) == self._device.index(self._device_component))
		self._update_device_selection()
		return None
	

	def _update_selected_device(self):
		if self._device_selection_follows_track_selection is True:
			self._update_device_selection()
		return None 
	

	def _update_linked_device_selection(self, device):
		#self.log_message('codec received ' + str(device.name))
		if self._device_component != None and device != None:
			if not self._device_component.is_locked():
				self._device_component.set_device(device)
	

	def _get_num_tracks(self):
		return self.num_tracks
	

	def _update_device_selection(self): #new method: code to verify
		#self.log_message('_update_device_selection')
		if self._device_component != None:
			if not self._device_component.is_locked():
				track = self.song().view.selected_track
				device_to_select = track.view.selected_device
				if ((device_to_select == None) and (len(track.devices) > 0)):
					device_to_select = track.devices[0]
				if (device_to_select != None):
					self.song().view.select_device(device_to_select)
				self._device_component.set_device(device_to_select)
 	

	def _channelstrip_mute_value(self, channelstrip):
		def _mute_value(value):
			if not self._shift_pressed:
				self.log_message('shift not pressed')
				ChannelStripComponent._mute_value(channelstrip, value)
		return _mute_value
		
	

	def _channelstrip_solo_value(self, channelstrip):
		def _solo_value(value):
			if not self._shift_pressed:
				ChannelStripComponent._solo_value(channelstrip, value)
		return _solo_value
		
	

	def _mixer_next_track_value(self, mixer):
		def _next_track_value(value):
			if not self._shift_pressed:
				MixerComponent._next_track_value(mixer, value)
		return _next_track_value
		
	

	def _mixer_prev_track_value(self, mixer):
		def _prev_track_value(value):
			if not self._shift_pressed:
				MixerComponent._prev_track_value(mixer, value)
		return _prev_track_value
Esempio n. 7
0
class OhmModes(ControlSurface):
	__module__ = __name__
	__doc__ = " OhmModes controller script "


	def __init__(self, c_instance):
		"""everything except the '_on_selected_track_changed' override and 'disconnect' runs from here"""
		ControlSurface.__init__(self, c_instance)
		self.set_suppress_rebuild_requests(True) # Turn off rebuild MIDI map until after we're done setting up

		"""MonoComponent specific variables - best not change these unless you know what you're doing"""
		self._version_check = 'b994'
		self._host_name = 'Ohm'
		self._color_type = 'OhmRGB'
		self._hosts = []
		self.hosts = []
		self._client = [None for index in range(6)]
		self._active_client = None

		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< OhmModes ' + str(self._version_check) + ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>') 		

		self._rgb = 0
		self._timer = 0
		self._touched = 0
		self.flash_status = 1
		self._backlight = 127
		self._backlight_type = 'static'
		self._ohm = 127
		self._ohm_type = 'static'
		self._pad_translations = PAD_TRANSLATION
		self._device_selection_follows_track_selection = FOLLOW
		self._keys_octave = 5
		self._keys_scale = 0

		self._tempo_buttons = None
		self._setup_monobridge()
		self._setup_controls()
		self._setup_transport_control() # Run the transport setup part of the script
		self._setup_mixer_control() # Setup the mixer object
		self._setup_session_control()  # Setup the session object 
		self._setup_device_control() # Setup the device object
		self._setup_crossfader()
		self._setup_ohmmod()
		self._setup_switchboard()
		self._setup_modes() 
		self._assign_page_constants()
		self._last_device = None

		self.set_suppress_rebuild_requests(False) #Turn rebuild back on, now that we're done setting up

		self.song().view.add_selected_track_listener(self._update_selected_device)
		self.show_message('OhmModes Control Surface Loaded')
		self._send_midi(tuple(switchxfader))
		if FORCE_TYPE is True:
			self._rgb = FORCE_COLOR_TYPE
		else:
			self.schedule_message(10, self.query_ohm, None)
	

	def query_ohm(self):
		#self.log_message('querying Ohm')
		self._send_midi(tuple(check_model))

	

	def update_display(self):
		""" Live -> Script
		Aka on_timer. Called every 100 ms and should be used to update display relevant
		parts of the controller
		"""
		for message in self._scheduled_messages:
			message['Delay'] -= 1
			if (message['Delay'] == 0):
				if (message['Parameter'] != None):
					message['Message'](message['Parameter'])
				else:
					message['Message']()
					del self._scheduled_messages[self._scheduled_messages.index(message)]

		for callback in self._timer_callbacks:
			callback()

		self._timer = (self._timer + 1) % 256
		self.flash()
		self.strobe()
	

	def _setup_monobridge(self):
		self._monobridge = MonoBridgeElement(self)
		self._monobridge.name = 'MonoBridge'
	

	def get_device_bank(self):
		return self._device._bank_index
	

	def _setup_controls(self):
		is_momentary = True
		self._fader = [None for index in range(8)]
		self._dial = [None for index in range(16)]
		self._button = [None for index in range(8)]
		self._menu = [None for index in range(6)]
		for index in range(8):
			self._fader[index] = MonoEncoderElement2(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self)
			#self._fader[index].name = 'Fader_' + str(index), self
		for index in range(8):
			self._button[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self)
		for index in range(16):
			self._dial[index] = CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), index, self)
			#self._dial[index].name = 'Dial_' + str(index)
		self._knobs = []
		for index in range(12):
			self._knobs.append(self._dial[index])
		for index in range(6):
			self._menu[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self)	
		self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute)
		self._crossfader.name = "Crossfader"
		self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		self._shift_l = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Page_Button_Left', self)
		self._shift_r = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Page_Button_Right', self)
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		self._grid = [None for index in range(8)]
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		for column in range(8):
			self._grid[column] = [None for index in range(8)]
			for row in range(8):
				self._grid[column][row] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (column * 8) + row, 'Grid_' + str(column) + '_' + str(row), self)
		for row in range(5):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])
			self._matrix.add_row(tuple(button_row)) 
		for row in range(8):
			button_row = []
			for column in range(8):
				button_row.append(self._grid[column][row])
			self._monomod.add_row(tuple(button_row))

		"""We'll also need to assign some of our controls to ButtonMatrixElements so that we can use them with the Session Zoom and the Mod components"""
		"""We use the same formula here:  first we create the holders:"""
		self._mod_matrix = ButtonMatrixElement()				#this is a standard _Framework object used by many of the other scripts
		self._mod_matrix.name = 'Matrix'
		self._dial_matrix = EncoderMatrixElement(self)		#this is a special Mono object, used specifically for the mod components
		self._dial_matrix.name = 'Dial_Matrix'
		self._dial_button_matrix = ButtonMatrixElement()	#this is a special Mono object, used specifically for the mod components
		self._dial_button_matrix.name = 'Dial_Button_Matrix'
		
		"""And then we fill the with the control elements that are assigned to them"""
		for row in range(4):		#we have 4 rows, and 4 columns, forming the 4x4 grid in the center of the controller
			button_row = []			#since the matrix is two dimensional, first we create the outer array,
			for column in range(4):
				button_row.append(self._grid[column+4][row])		#then we create the inner array.  The process is the same for the other controls here.
			self._mod_matrix.add_row(tuple(button_row)) 				#add_row() is a method of the ButtonMatrixElement.  You can look in its parent module to see how it works
		for row in range(3):
			dial_row = []
			for column in range(4):
				dial_row.append(self._dial[(row*4) + column])
			self._dial_matrix.add_row(tuple(dial_row))
		for row in range(3):
			dial_button_row = []
			for column in range(4):
				dial_button_row.append(self._grid[column][row])
			self._dial_button_matrix.add_row(tuple(dial_button_row))
		self._key = [self._grid[KEYS[index][1]][KEYS[index][0]] for index in range(32)]
		self._encoder = [self._dial[index] for index in range(12)]
		self._key_matrix = ButtonMatrixElement()
		button_row = []						#since we only use one row for the chopper, we can define a 1 dimensional button matrix for this one.   
		for column in range(16):			#We use the ButtonMatrixObject because it takes care of setting up callbacks for all the buttons easily when we need them later
			button_row.append(self._key[16 + column])
		self._key_matrix.add_row(tuple(button_row))
	

	def _setup_ohmmod(self):
		self._host = MonomodComponent(self)
		self._host.name = 'Monomod_Host'
		self.hosts = [self._host]
		self._hosts = [self._host]
		for index in range(6):
			self._client[index] = MonoClient(self, index)
			self._client[index].name = 'Client_' + str(index)
			#self._client[index]._mod_dial = self._encoder[index]
			self._client[index]._device_component.set_parameter_controls(tuple([self._dial[num] for num in range(12)]))		#assign the encoders to the clients so that we can control device parameters through our client
			self._client[index]._control_defs = {'dials':self._dial_matrix, 'buttons':self._dial_button_matrix, 'grid':self._mod_matrix, 'keys':self._key, 'knobs':[self._dial[num+12] for num in range(4)]}  #assign controls that raw data will be addressed at
		self._host._active_client = self._client[0]
		self._host._active_client._is_active = True
		self._host.connect_to_clients(self)
	

	def _setup_switchboard(self):
		self._switchboard = SwitchboardElement(self, self._client)
		self._switchboard.name = 'Switchboard'
	

	def _setup_modes(self):
		self._shift_mode = ShiftModeComponent(self) 
		self._shift_mode.name = 'Shift_Mode'
		self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r, self._livid)
		self._scale_mode = ScaleModeComponent(self)
		self._scale_mode.name = "Scale_Mode"
		self._octave_mode = OctaveModeComponent(self)
		self._octave_mode.name = "Octave_Mode"
		self._modNum = ModNumModeComponent(self, self.modNum_update) 
		self._modNum.name = 'Mod_Number'
		self._modNum.set_mode = self._modNum_set_mode(self._modNum)
		self._modNum.set_mode_buttons([self._menu[index] for index in range(6)])
	

	def _modNum_set_mode(self, modNum):
		def set_mode(mode):
			if modNum._is_enabled == True:
				assert isinstance(mode, int)
				assert (mode in range(modNum.number_of_modes()))
				if (modNum._mode_index != mode):
					modNum._mode_index = mode
					modNum.update()
		return set_mode
		
	

	def _setup_transport_control(self):
		self._transport = TransportComponent() 
		self._transport.name = 'Transport'
	

	def _setup_mixer_control(self):
		is_momentary = True
		self._num_tracks = (7) #A mixer is one-dimensional; 
		global mixer
		mixer = SpecialMixerComponent(7, 0, True, False)
		mixer.name = 'Mixer'
		self._mixer = mixer
		mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		for index in range(7):
			mixer.channel_strip(index).set_volume_control(self._fader[index])
		for index in range(7):
			mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			mixer.track_eq(index).name = 'Mixer_EQ_' + str(index)
			mixer.channel_strip(index)._invert_mute_feedback = True
		self.song().view.selected_track = mixer.channel_strip(0)._track #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
	

	def _setup_session_control(self):
		is_momentary = True
		num_tracks = 7
		num_scenes = 5 
		global session
		session = SessionComponent(num_tracks, num_scenes)
		session.name = "Session"
		self._session = session	
		session.set_offsets(0, 0)	 
		self._scene = [None for index in range(6)]
		for row in range(num_scenes):
			self._scene[row] = session.scene(row)
			self._scene[row].name = 'Scene_' + str(row)
			for column in range(num_tracks):
				clip_slot = self._scene[row].clip_slot(column)
				clip_slot.name = str(column) + '_Clip_Slot_' + str(row)		
		session.set_mixer(self._mixer)
		self._session_zoom = SessionZoomingComponent(session)	 
		self._session_zoom.name = 'Session_Overview'
	

	def _assign_session_colors(self):
		self.log_message('assign session colors')
		num_tracks = 7
		num_scenes = 5 
		self._session.set_stop_track_clip_value(STOP_CLIP_COLOR[self._rgb])
		for row in range(num_scenes): 
			for column in range(num_tracks):
				self._scene[row].clip_slot(column).set_triggered_to_play_value(CLIP_TRIGD_TO_PLAY_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_triggered_to_record_value(CLIP_TRIGD_TO_RECORD_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_stopped_value(CLIP_STOPPED_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_recording_value(CLIP_RECORDING_COLOR[self._rgb])		
		self._session_zoom.set_stopped_value(ZOOM_STOPPED_COLOR[self._rgb])
		self._session_zoom.set_playing_value(ZOOM_PLAYING_COLOR[self._rgb])
		self._session_zoom.set_selected_value(ZOOM_SELECTED_COLOR[self._rgb])
		for row in range(8):
			for column in range(8):
				self._grid[column][row].set_force_next_value()
		self._session.on_scene_list_changed()
		self._shift_mode.update()
	

	def _setup_device_control(self):
		self._device = DeviceComponent()
		self._device.name = 'Device_Component'
		self.set_device_component(self._device)
		self._device_navigator = DetailViewControllerComponent()
		self._device_navigator.name = 'Device_Navigator'
		self._device_selection_follows_track_selection = FOLLOW
	

	def device_follows_track(self, val):
		self._device_selection_follows_track_selection = (val == 1)
		return self
	

	def _setup_crossfader(self):
		self._mixer.set_crossfader_control(self._crossfader)
	

	def disconnect(self):
		"""clean things up on disconnect"""
		self.song().view.remove_selected_track_listener(self._update_selected_device)
		self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= OhmModes log closed =--------------") #Create entry in log file
		ControlSurface.disconnect(self)
		return None
	

	def _get_num_tracks(self):
		return self.num_tracks
	

	def flash(self):
		#if(self.flash_status > 0):
		for row in range(8):
			if(self._button[row]._flash_state > 0):
				self._button[row].flash(self._timer)
			for column in range(8):
				button = self._grid[column][row]
				if(button._flash_state > 0):
					button.flash(self._timer)
	

	def strobe(self):
		if(self._backlight_type != 'static'):
			if(self._backlight_type is 'pulse'):
				self._backlight = int(math.fabs(((self._timer * 16) % 64) -32) +32)
			if(self._backlight_type is 'up'):
				self._backlight = int(((self._timer * 8) % 64) + 16)
			if(self._backlight_type is 'down'):
				self._backlight = int(math.fabs(int(((self._timer * 8) % 64) - 64)) + 16)
		self._send_midi(tuple([176, 27, int(self._backlight)]))
		if(self._ohm_type != 'static'):
			if(self._ohm_type is 'pulse'):
				self._ohm = int(math.fabs(((self._timer * 16) % 64) -32) +32)
			if(self._ohm_type is 'up'):
				self._ohm = int(((self._timer * 8) % 64) + 16)
			if(self._ohm_type is 'down'):
				self._ohm = int(math.fabs(int(((self._timer * 8) % 64) - 64)) + 16)
		self._send_midi(tuple([176, 63, int(self._ohm)]))
		self._send_midi(tuple([176, 31, int(self._ohm)]))	
	

	def deassign_matrix(self):
		self._host._set_knobs(None)
		self._host._set_button_matrix(None)
		self._host.set_enabled(False)
		self._modNum.set_enabled(False)
		self.assign_alternate_mappings(0)
		self._scale_mode.set_mode_buttons(None)
		self._scale_mode.set_enabled(False)
		self._octave_mode.set_mode_buttons(None)
		self._octave_mode.set_enabled(False)
		#self._session_zoom.set_button_matrix(None)
		self._session_zoom.set_enabled(False)
		self._session_zoom.set_nav_buttons(None, None, None, None)
		self._session.set_track_bank_buttons(None, None)
		self._session.set_scene_bank_buttons(None, None)
		self._transport.set_enabled(False)
		for column in range(4):
			#self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]]))
			self._mixer.track_eq(column)._gain_controls = None
			self._mixer.track_eq(column).set_enabled(False)	
		for column in range(7):
			self._mixer.channel_strip(column).set_crossfade_toggle(None)
			self._mixer.channel_strip(column).set_mute_button(None)
			self._mixer.channel_strip(column).set_solo_button(None)
			self._mixer.channel_strip(column).set_arm_button(None)
			self._mixer.channel_strip(column).set_send_controls(None)
			self._mixer.channel_strip(column).set_pan_control(None)
			self._mixer.track_eq(column).set_enabled(False)
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(None)
		for column in range(8):
			self._button[column]._on_value = SELECT_COLOR[self._rgb]
			for row in range(8):
				self._grid[column][row].set_channel(0)
				self._grid[column][row].release_parameter()
				self._grid[column][row].use_default_message()
				self._grid[column][row].set_enabled(True)
				self._grid[column][row].send_value(0, True)
				self._grid[column][row]._on_value = 127
				self._grid[column][row]._off_value = 0
		for index in range(6):
			self._menu[index]._on_value = 127
			self._menu[index]._off_value = 0
		for index in range(16):
			self._dial[index].use_default_message()
			self._dial[index].release_parameter()
			#self._dial[index].set_enabled(True)
		if(self._device._parameter_controls != None):
			for control in self._device._parameter_controls:
				control.release_parameter()
			self._device._parameter_controls = None
		self._device.set_enabled(False)
		self._device_navigator.set_enabled(False)
		self._mixer.update()
		self._matrix.reset()
		#self._transport.set_play_button(None)
		#self._transport.set_stop_button(None)	
		self.request_rebuild_midi_map()
	

	def _assign_page_constants(self):
		#self._session_zoom.set_zoom_button(self._button[7]) #commented out pn 070111
		self._session_zoom.set_zoom_button(self._grid[7][7]) #added pn 070111
		self._session_zoom.set_button_matrix(self._matrix)
		#self._session_zoom.set_enabled(True)
		for column in range(7):
			self._mixer.channel_strip(column).set_select_button(self._button[column])
			self._mixer.channel_strip(column).set_volume_control(self._fader[column])
		self._mixer.master_strip().set_volume_control(self._fader[7])
		self._mixer.master_strip().set_select_button(self._button[7]) #added pn 070111
		self._mixer.set_prehear_volume_control(self._dial[15])
		self._transport.set_play_button(self._menu[0])
		self._menu[0].send_value(PLAY_COLOR[self._rgb], True)	
		self._menu[0]._on_value = PLAY_COLOR[self._rgb]
		self._transport.set_stop_button(self._menu[1])
		self._menu[1]._off_value = STOP_COLOR[self._rgb]
		self._menu[1]._on_value = STOP_COLOR[self._rgb]
		self._menu[1].send_value(STOP_COLOR[self._rgb], True)	
		#self._livid._on_value = TAP_COLOR[self._rgb]
		#self._transport.set_tap_tempo_button(self._livid)
		#self._livid.send_value(TAP_COLOR, True)
		self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[4])
	

	def assign_page_0(self):
		self._backlight_type = 'static'
		#self._session_zoom.set_button_matrix(self._matrix)
		self._session_zoom.set_enabled(True)
		for column in range(7):
			self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6]._on_value = SOLO_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_solo_button(self._grid[column][6])
			self._grid[column][7]._on_value = ARM_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_arm_button(self._grid[column][7])
			self._mixer.channel_strip(column).set_pan_control(self._dial[column + 8])
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
		for column in range(4):
			self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column], self._dial[column + 4]]))
		for index in range(5):
			self._grid[7][index]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
			self._scene[index].set_launch_button(self._grid[7][index])
			self._grid[7][index].set_force_next_value()
			self._grid[7][index].turn_off()
		for index in range(4):
			self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]
		self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
		self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])	
		self._menu[0]._on_value = PLAY_COLOR[self._rgb]
		self._menu[1]._off_value = STOP_COLOR[self._rgb]
		self._menu[1]._on_value = STOP_COLOR[self._rgb]
		self._transport.set_enabled(True)
	

	def assign_page_1(self):
		self._backlight_type = 'pulse'
		self._session_zoom.set_enabled(False)
		for column in range(4):
			for row in range(4):
				self._grid[column][row].set_channel(PAGE1_DRUM_CHANNEL)
				self._grid[column][row].set_identifier(PAGE1_DRUM_MAP[column][row])
				self._grid[column][row].send_value(DRUM_COLOR[self._rgb], True)
				self._grid[column][row].set_enabled(False)
				self._grid[column + 4][row].set_channel(PAGE1_BASS_CHANNEL)
				self._grid[column + 4][row].set_identifier(PAGE1_BASS_MAP[column][row])
				self._grid[column + 4][row].send_value(BASS_COLOR[self._rgb], True)
				self._grid[column + 4][row].set_enabled(False)
		scale_mode_buttons = []
		for column in range(8):
			for row in range(3):
				self._grid[column][row + 4].set_enabled(False)
				self._grid[column][row + 4].set_channel(PAGE1_KEYS_CHANNEL)
				self._grid[column][row + 4].set_identifier(int(PAGE1_KEYS_MAP[column][row]) + int(PAGE1_MODES_MAP[self._scale_mode._mode_index][column]) + int(self._octave_mode._mode_index * 12))
				self._grid[column][row + 4].send_value(KEYS_COLOR[self._rgb], True)
			for row in range(1):
				scale_mode_buttons.append(self._grid[column][7])
		self._scale_mode.set_mode_buttons(tuple(scale_mode_buttons))
		self._scale_mode.set_enabled(True)
		self._octave_mode.set_mode_buttons(tuple([self._menu[5], self._menu[2]]))
		self._octave_mode.set_enabled(True)
		for column in range(7):
			self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column + 8]]))
			self._mixer.channel_strip(column).set_arm_button(self._button[column])
		self._device.set_enabled(True)
		device_param_controls = []
		for index in range(8):
			device_param_controls.append(self._dial[index])
		self._device.set_parameter_controls(tuple(device_param_controls))
		self._menu[0]._on_value = (PLAY_COLOR[self._rgb])
		for index in range(4):
			self._menu[2 + index]._on_value = (DEVICE_NAV_COLOR[self._rgb])
		self._device_navigator.set_enabled(True)
		self._menu[0]._on_value = PLAY_COLOR[self._rgb]
		self._menu[1]._off_value = STOP_COLOR[self._rgb]
		self._menu[1]._on_value = STOP_COLOR[self._rgb]
		self._transport.set_enabled(True)
	

	def assign_page_2(self):
		self._backlight_type = 'up'
		#self._session_zoom.set_button_matrix(self._matrix)
		self._session_zoom.set_enabled(True)
		for column in range(7):
			self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6]._on_value = CROSSFADE_ASSIGN_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_crossfade_toggle(self._grid[column][6])
			self._grid[column][7].set_channel(2)
			self._grid[column][7].set_identifier(column)
			self._grid[column][7].reset()
			self._grid[column][7].set_enabled(False)
			self._grid[column][7].send_value(4, True)
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
		for row in range(5):
			self._grid[7][row]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
			self._scene[row].set_launch_button(self._grid[7][row])
			self._grid[7][row].set_force_next_value()
			self._grid[7][row].turn_off()
		for column in range(4):
			self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]]))
			self._mixer.track_eq(column).set_enabled(True)	
		for column in range(3):
			self._mixer.channel_strip(column+4).set_pan_control(self._dial[column + 12])
		for index in range(4):
			self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]
		self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
		self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])
		self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]])
		self._menu[0]._on_value = PLAY_COLOR[self._rgb]
		self._menu[1]._off_value = STOP_COLOR[self._rgb]
		self._menu[1]._on_value = STOP_COLOR[self._rgb]
		self._transport.set_enabled(True)
	

	"""
	def assign_page_0(self):
		self._backlight_type = 'static'
		#self._session_zoom.set_button_matrix(self._matrix)
		self._transport.set_play_button(self._menu[0])
		self._transport.set_stop_button(self._menu[1])
		self._session_zoom.set_enabled(True)
		for column in range(7):
			self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6]._on_value = SOLO_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_solo_button(self._grid[column][6])
			self._grid[column][7]._on_value = ARM_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_arm_button(self._grid[column][7])
			self._mixer.channel_strip(column).set_pan_control(self._dial[column + 8])
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
		for column in range(4):
			self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column], self._dial[column + 4]]))
		for index in range(5):
			self._grid[7][index]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
			self._scene[index].set_launch_button(self._grid[7][index])
		for index in range(4):
			self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]
		self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
		self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])
	

	def assign_page_1(self):
		self._backlight_type = 'pulse'
		self._transport.set_play_button(self._menu[0])
		self._transport.set_stop_button(self._menu[1])
		self._session_zoom.set_enabled(False)
		for column in range(8):
			for row in range(8):
				self._grid[row][column].set_channel(JESSE_MAP_CHAN)
				self._grid[row][column].set_identifier(JESSE_MAP[column][row])
				self._grid[row][column].send_value(JESSE_MAP_COLORS[self._rgb], True)
				self._grid[row][column].set_enabled(False)
				""self._grid[column + 4][row].set_channel(PAGE1_BASS_CHANNEL)
				self._grid[column + 4][row].set_identifier(PAGE1_BASS_MAP[column][row])
				self._grid[column + 4][row].send_value(BASS_COLOR[self._rgb], True)
				self._grid[column + 4][row].set_enabled(False)
		scale_mode_buttons = []
		for column in range(8):
			for row in range(3):
				self._grid[column][row + 4].set_enabled(False)
				self._grid[column][row + 4].set_channel(PAGE1_KEYS_CHANNEL)
				self._grid[column][row + 4].set_identifier(int(PAGE1_KEYS_MAP[column][row]) + int(PAGE1_MODES_MAP[self._scale_mode._mode_index][column]) + int(self._octave_mode._mode_index * 12))
				self._grid[column][row + 4].send_value(KEYS_COLOR[self._rgb], True)
			for row in range(1):
				scale_mode_buttons.append(self._grid[column][7])""
		#self._scale_mode.set_mode_buttons(tuple(scale_mode_buttons))
		#self._scale_mode.set_enabled(True)
		#self._octave_mode.set_mode_buttons(tuple([self._menu[5], self._menu[2]]))
		#self._octave_mode.set_enabled(True)
		for column in range(7):
			self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column + 8]]))
			self._mixer.channel_strip(column).set_arm_button(self._button[column])
		self._device.set_enabled(True)
		device_param_controls = []
		for index in range(8):
			device_param_controls.append(self._dial[index])
		self._device.set_parameter_controls(tuple(device_param_controls))
		for index in range(4):
			self._menu[2 + index]._on_value = (DEVICE_NAV_COLOR[self._rgb])
		self._device_navigator.set_enabled(True)
	

	def assign_page_2(self):
		self._backlight_type = 'up'
		self._transport.set_play_button(self._menu[0])
		self._transport.set_stop_button(self._menu[1])
		#self._session_zoom.set_button_matrix(self._matrix)
		self._session_zoom.set_enabled(True)
		for column in range(7):
			self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6]._on_value = CROSSFADE_ASSIGN_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_crossfade_toggle(self._grid[column][6])
			self._grid[column][7].set_channel(2)
			self._grid[column][7].set_identifier(column)
			self._grid[column][7].reset()
			self._grid[column][7].set_enabled(False)
			self._grid[column][7].send_value(4, True)
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
		for row in range(5):
			self._grid[7][row]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
			self._scene[row].set_launch_button(self._grid[7][row])
		for column in range(4):
			self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]]))
			self._mixer.track_eq(column).set_enabled(True)	
		for column in range(3):
			self._mixer.channel_strip(column+4).set_pan_control(self._dial[column + 12])
		for index in range(4):
			self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]
		self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
		self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])
		self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]])
	
	"""


	def assign_mod(self):
		self.deassign_matrix()
		#self.set_local_ring_control(self._host._active_client._local_ring_control)
		self._host.set_enabled(True)
		self._modNum.set_enabled(True)
		self._host._set_dial_matrix(self._dial_matrix, self._dial_button_matrix)
		self._host._set_button_matrix(self._mod_matrix)
		self._host._set_key_buttons(tuple(self._key))
		if not self._host._active_client.is_connected():
			self.assign_alternate_mappings(self._modNum._mode_index + 1)
	

	def modNum_update(self):
		if self._modNum._is_enabled == True:
			self.assign_alternate_mappings(0)
			self._host._select_client(int(self._modNum._mode_index))
			self._host.display_active_client()
			if not self._host._active_client.is_connected():
				self.assign_alternate_mappings(self._modNum._mode_index + 1)
			for button in self._modNum._modes_buttons:
				if self._modNum._mode_index == self._modNum._modes_buttons.index(button):
					button.send_value(1)
				else:
					button.send_value(self._client[self._modNum._modes_buttons.index(button)]._mod_color)
				#button.send_value(int(self._modNum._mode_index == self._modNum._modes_buttons.index(button))*self._host._active_client._mod_color)
	

	def assign_alternate_mappings(self, chan):
		for column in range(8):
			for row in range(8):
				#self._grid[column][row].set_identifier(OHM_MAP_ID[column][row])
				self._grid[column][row].set_channel(chan)
				#self._grid[column][row].send_value(OHM_MAP_VALUE[column][row])
				self._grid[column][row].set_enabled(chan is 0)
		for knob in self._encoder:
			knob.set_channel(chan)
			knob.set_enabled(chan is 0)
		self.request_rebuild_midi_map()
	

	def display_mod_colors(self):
		#for index in range(6):							#set up a recursion of 6
		#	self._modNum._modes_buttons[index].send_value(self._client[index]._mod_color)		#update the modLEDs to display the color assigned to its contained mod
		pass
	

	def _update_selected_device(self):
		if self._device_selection_follows_track_selection is True:
			track = self.song().view.selected_track
			device_to_select = track.view.selected_device
			if device_to_select == None and len(track.devices) > 0:
				device_to_select = track.devices[0]
			if device_to_select != None:
				self.song().view.select_device(device_to_select)
			#self._device.set_device(device_to_select)
			self.set_appointed_device(device_to_select)
			#self._device_selector.set_enabled(True)
			self.request_rebuild_midi_map()
		return None
	

	def handle_sysex(self, midi_bytes):
		#self.log_message(str('>>sysexIN') + str(midi_bytes))
		if len(midi_bytes) > 10:
			#self.log_message(str('>>sysex>10') + str(midi_bytes[:11]))
			if midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 7]):
				self.log_message(str('>>>color detected'))
				self._rgb = 0
			elif midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 2]):
				self.log_message(str('>>>mono detected'))
				self._rgb = 1
		self._assign_session_colors()
	

	"""this method can be linked to from m4l, and provides a way to update the parameter value of an assigned DeviceComponent parameter control"""
	def to_encoder(self, num, val):
		rv=int(val*127)
		self._device._parameter_controls[num].receive_value(rv)
		p = self._device._parameter_controls[num]._parameter_to_map_to
		newval = (val * (p.max - p.min)) + p.min
		p.value = newval
	

	"""this method sets the instance variable for local ring control, and sends the appropriate sysex string to change states on the CNTRLR"""
	def set_local_ring_control(self, val = 1):
		self._local_ring_control = (val!=0)
		"""if(self._local_ring_control is True):
			self._send_midi(tuple([240, 0, 1, 97, 8, 32, 0, 247]))
		else:
			self._send_midi(tuple([240, 0, 1, 97, 8, 32, 1, 247]))"""
	

	"""this method sets the instance variable for absolute encoder changes, and sends the appropriate sysex string to change states on the CNTRLR"""			
	def set_absolute_mode(self, val = 1):
		self._absolute_mode = (val!=0)
		"""if self._absolute_mode is True:
			self._send_midi(tuple([240, 0, 1, 97, 8, 17, 0, 0, 0, 0, 0, 0, 0, 0, 247]))
		else:
			self._send_midi(tuple([240, 0, 1, 97, 8, 17, 127, 127, 127, 127, 127, 127, 127, 127, 247]))"""
	

	"""this method is used to update the individual elements of the encoder rings when the CNTRLR is in local ring control mode"""
	def send_ring_leds(self):
		"""if self._host._is_enabled == True:
			leds = [240, 0, 1, 97, 8, 31]
			for index in range(12):
				wheel = self._encoder[index]
				bytes = wheel._get_ring()
				leds.append(bytes[0])
				leds.append(int(bytes[1]) + int(bytes[2]))
			leds.append(247)
			self._send_midi(tuple(leds))"""
		pass
	

	def receive_midi(self, midi_bytes):
		""" Live -> Script
		MIDI messages are only received through this function, when explicitly 
		forwarded in 'build_midi_map'.
		"""
		assert (midi_bytes != None)
		assert isinstance(midi_bytes, tuple)
		##self.log_message('got message' + str(midi_bytes))
		self.set_suppress_rebuild_requests(True)
		if (len(midi_bytes) is 3):
			msg_type = (midi_bytes[0] & 240)
			forwarding_key = [midi_bytes[0]]
			if (msg_type is not MIDI_PB_TYPE):
				forwarding_key.append(midi_bytes[1])
			if (tuple(forwarding_key) in self._forwarding_registry.keys()):
				recipient = self._forwarding_registry[tuple(forwarding_key)]
				if (recipient != None):
					recipient.receive_value(midi_bytes[2])
			else:
				self.log_message(('Got unknown message: ' + str(midi_bytes)))
		else:
			self.handle_sysex(midi_bytes)
		self.set_suppress_rebuild_requests(False)		 
	

	def _set_tempo_buttons(self, buttons):
		if self._tempo_buttons != None:
			self._tempo_buttons[0].remove_value_listener(self._tempo_value)
			self._tempo_buttons[1].remove_value_listener(self._tempo_value)
		self._tempo_buttons = buttons
		if buttons != None:
			for button in buttons:
				assert isinstance(button, FlashingButtonElement)
			self._tempo_buttons[0].set_on_off_values(4, 0)
			self._tempo_buttons[0].add_value_listener(self._tempo_value, True)
			self._tempo_buttons[1].set_on_off_values(4, 0)
			self._tempo_buttons[1].add_value_listener(self._tempo_value, True)
			self._tempo_buttons[0].turn_on()
			self._tempo_buttons[1].turn_on()
	

	def _tempo_value(self, value, sender):
		if (value > 0) and (self._tempo_buttons.index(sender) == 0):
			self.song().tempo = round(min((self.song().tempo + 1), 999))
		elif (value > 0) and (self._tempo_buttons.index(sender) == 1):
			self.song().tempo = round(max((self.song().tempo - 1), 20))
	

	"""m4l bridge"""
	def generate_strip_string(self, display_string):
		#self.log_message(display_string)
		NUM_CHARS_PER_DISPLAY_STRIP = 12
		if (not display_string):
			return (' ' * NUM_CHARS_PER_DISPLAY_STRIP)
		if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.endswith('dB') and (display_string.find('.') != -1))):
			display_string = display_string[:-2]
		if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			for um in [' ',
			 'i',
			 'o',
			 'u',
			 'e',
			 'a']:
				while ((len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1)):
					um_pos = display_string.rfind(um, 1)
					display_string = (display_string[:um_pos] + display_string[(um_pos + 1):])
		else:
			display_string = display_string.center((NUM_CHARS_PER_DISPLAY_STRIP - 1))
		ret = u''
		for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			if ((ord(display_string[i]) > 127) or (ord(display_string[i]) < 0)):
				ret += ' '
			else:
				ret += display_string[i]

		ret += ' '
		#assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
		return ret
	

	def notification_to_bridge(self, name, value, sender):
		if(isinstance(sender, tuple([MonoEncoderElement2, CodecEncoderElement]))):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))
	

	def touched(self):
		if self._touched is 0:
			self._monobridge._send('touch', 'on')
			self.schedule_message(2, self.check_touch)
		self._touched +=1
	

	def check_touch(self):
		if self._touched > 5:
			self._touched = 5
		elif self._touched > 0:
			self._touched -= 1
		if self._touched is 0:
			self._monobridge._send('touch', 'off')
		else:
			self.schedule_message(2, self.check_touch)
	

	def get_clip_names(self):
		clip_names = []
		for scene in self._session._scenes:
			for clip_slot in scene._clip_slots:
				if clip_slot.has_clip() is True:
					clip_names.append(clip_slot._clip_slot)##.clip.name)
					return clip_slot._clip_slot
					##self.log_message(str(clip_slot._clip_slot.clip.name))
		return clip_names
	

	def shift_update(self):
		pass
Esempio n. 8
0
	def _setup_controls(self):
		is_momentary = True
		self._fader = [None for index in range(8)]
		self._dial = [None for index in range(16)]
		self._button = [None for index in range(8)]
		self._menu = [None for index in range(6)]
		for index in range(8):
			self._fader[index] = MonoEncoderElement2(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self)
			#self._fader[index].name = 'Fader_' + str(index), self
		for index in range(8):
			self._button[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self)
		for index in range(16):
			self._dial[index] = CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), index, self)
			#self._dial[index].name = 'Dial_' + str(index)
		self._knobs = []
		for index in range(12):
			self._knobs.append(self._dial[index])
		for index in range(6):
			self._menu[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self)	
		self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute)
		self._crossfader.name = "Crossfader"
		self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		self._shift_l = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Page_Button_Left', self)
		self._shift_r = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Page_Button_Right', self)
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		self._grid = [None for index in range(8)]
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		for column in range(8):
			self._grid[column] = [None for index in range(8)]
			for row in range(8):
				self._grid[column][row] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (column * 8) + row, 'Grid_' + str(column) + '_' + str(row), self)
		for row in range(5):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])
			self._matrix.add_row(tuple(button_row)) 
		for row in range(8):
			button_row = []
			for column in range(8):
				button_row.append(self._grid[column][row])
			self._monomod.add_row(tuple(button_row))

		"""We'll also need to assign some of our controls to ButtonMatrixElements so that we can use them with the Session Zoom and the Mod components"""
		"""We use the same formula here:  first we create the holders:"""
		self._mod_matrix = ButtonMatrixElement()				#this is a standard _Framework object used by many of the other scripts
		self._mod_matrix.name = 'Matrix'
		self._dial_matrix = EncoderMatrixElement(self)		#this is a special Mono object, used specifically for the mod components
		self._dial_matrix.name = 'Dial_Matrix'
		self._dial_button_matrix = ButtonMatrixElement()	#this is a special Mono object, used specifically for the mod components
		self._dial_button_matrix.name = 'Dial_Button_Matrix'
		
		"""And then we fill the with the control elements that are assigned to them"""
		for row in range(4):		#we have 4 rows, and 4 columns, forming the 4x4 grid in the center of the controller
			button_row = []			#since the matrix is two dimensional, first we create the outer array,
			for column in range(4):
				button_row.append(self._grid[column+4][row])		#then we create the inner array.  The process is the same for the other controls here.
			self._mod_matrix.add_row(tuple(button_row)) 				#add_row() is a method of the ButtonMatrixElement.  You can look in its parent module to see how it works
		for row in range(3):
			dial_row = []
			for column in range(4):
				dial_row.append(self._dial[(row*4) + column])
			self._dial_matrix.add_row(tuple(dial_row))
		for row in range(3):
			dial_button_row = []
			for column in range(4):
				dial_button_row.append(self._grid[column][row])
			self._dial_button_matrix.add_row(tuple(dial_button_row))
		self._key = [self._grid[KEYS[index][1]][KEYS[index][0]] for index in range(32)]
		self._encoder = [self._dial[index] for index in range(12)]
		self._key_matrix = ButtonMatrixElement()
		button_row = []						#since we only use one row for the chopper, we can define a 1 dimensional button matrix for this one.   
		for column in range(16):			#We use the ButtonMatrixObject because it takes care of setting up callbacks for all the buttons easily when we need them later
			button_row.append(self._key[16 + column])
		self._key_matrix.add_row(tuple(button_row))