Example #1
0
class AumPC40(APC40):


	def __init__(self, c_instance, *a, **k):
		super(AumPC40, self).__init__(c_instance, *a, **k)
		self._monomod_version = 'b996'
		self._host_name = 'AumPC'
		self._color_type = 'APC'
		self._timer = 0
		self._touched = 0
		self.flash_status = False
		with self.component_guard():
			self._setup_monobridge()
			self._setup_mod()
			self._device_component._current_bank_details = self._make_current_bank_details(self._device_component)
	

	def disconnect(self):
		super(AumPC40, self).disconnect()
		rebuild_sys()
	

	def _create_controls(self):
		make_on_off_button = partial(make_button, skin=self._default_skin)
		make_color_button = partial(make_button, skin=self._color_skin)
		self._shift_button = make_button(0, 98, resource_type=PrioritizedResource, name='Shift_Button')
		self._right_button = make_button(0, 96, name='Bank_Select_Right_Button')
		self._left_button = make_button(0, 97, name='Bank_Select_Left_Button')
		self._up_button = make_button(0, 94, name='Bank_Select_Up_Button')
		self._down_button = make_button(0, 95, name='Bank_Select_Down_Button')
		self._session_matrix = ButtonMatrixElement(name='Button_Matrix')
		self._scene_launch_buttons = [ make_color_button(0, index + 82, name='Scene_%d_Launch_Button' % index, cs = self) for index in xrange(SESSION_HEIGHT) ]
		self._track_stop_buttons = [ make_color_button(index, 52, name='Track_%d_Stop_Button' % index, cs = self) for index in xrange(SESSION_WIDTH) ]
		self._stop_all_button = make_color_button(0, 81, name='Stop_All_Clips_Button', cs = self)
		self._matrix_rows_raw = [ [ make_color_button(track_index, scene_index + 53, name='%d_Clip_%d_Button' % (track_index, scene_index), cs = self) for track_index in xrange(SESSION_WIDTH) ] for scene_index in xrange(SESSION_HEIGHT) ]
		for row in self._matrix_rows_raw:
			self._session_matrix.add_row(row)

		self._selected_slot_launch_button = make_pedal_button(67, name='Selected_Slot_Launch_Button')
		self._selected_scene_launch_button = make_pedal_button(64, name='Selected_Scene_Launch_Button')
		self._volume_controls = []
		self._arm_buttons = []
		self._original_solo_buttons = []
		self._original_mute_buttons = []
		self._select_buttons = []
		for index in xrange(MIXER_SIZE):
			self._volume_controls.append(make_slider(index, 7, name='%d_Volume_Control' % index, num=index, script = self))
			self._arm_buttons.append(make_on_off_button(index, 48, name='%d_Arm_Button' % index, cs = self))
			self._original_solo_buttons.append(make_on_off_button(index, 49, name='%d_Solo_Button' % index, cs = self))
			self._original_mute_buttons.append(make_on_off_button(index, 50, name='%d_Mute_Button' % index, cs = self))
			self._select_buttons.append(make_on_off_button(index, 51, name='%d_Select_Button' % index, cs = self))

		self._crossfader_control = make_slider(0, 15, name='Crossfader', script = self)
		self._master_volume_control = make_slider(0, 14, name='Master_Volume_Control', script = self)
		self._master_select_button = make_on_off_button(0, 80, name='Master_Select_Button', cs = self)
		self._prehear_control = make_encoder(0, 47, name='Prehear_Volume_Control', script = self)
		self._device_bank_buttons = []
		self._device_param_controls_raw = []
		bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button', 'Detail_View_Button', 'Rec_Quantization_Button', 'Midi_Overdub_Button', 'Metronome_Button')
		for index in range(8):
			self._device_bank_buttons.append(make_on_off_button(0, 58 + index, name=bank_button_labels[index]))
			encoder_name = 'Device_Control_%d' % index
			ringed_encoder = make_ring_encoder(16 + index, 24 + index, name=encoder_name, num = index + 8, script = self)
			self._device_param_controls_raw.append(ringed_encoder)

		self._play_button = make_button(0, 91, name='Play_Button')
		self._stop_button = make_button(0, 92, name='Stop_Button')
		self._record_button = make_button(0, 93, name='Record_Button')
		self._nudge_up_button = make_button(0, 100, name='Nudge_Up_Button')
		self._nudge_down_button = make_button(0, 101, name='Nudge_Down_Button')
		self._tap_tempo_button = make_button(0, 99, name='Tap_Tempo_Button')
		self._global_bank_buttons = []
		self._global_param_controls = []
		for index in range(8):
			encoder_name = 'Track_Control_%d' % index
			ringed_encoder = make_ring_encoder(48 + index, 56 + index, name=encoder_name, num = index, script = self)
			self._global_param_controls.append(ringed_encoder)

		self._global_bank_buttons = [ make_on_off_button(0, 87 + index, name=name) for index, name in enumerate(('Pan_Button', 'Send_A_Button', 'Send_B_Button', 'Send_C_Button')) ]
		self._device_clip_toggle_button = self._device_bank_buttons[0]
		self._device_on_off_button = self._device_bank_buttons[1]
		self._detail_left_button = self._device_bank_buttons[2]
		self._detail_right_button = self._device_bank_buttons[3]
		self._detail_toggle_button = self._device_bank_buttons[4]
		self._rec_quantization_button = self._device_bank_buttons[5]
		self._overdub_button = self._device_bank_buttons[6]
		self._metronome_button = self._device_bank_buttons[7]

		self._monomod = ButtonMatrixElement(name = 'Monomod')
		for row in self._matrix_rows_raw:
			self._monomod.add_row(row)
		self._monomod.add_row(self._track_stop_buttons)
		self._monomod.add_row(self._select_buttons)
		self._monomod.add_row(self._original_mute_buttons)
		#self._doublepress_detail_button = DoublePressElement(self._detail_toggle_button)

		def wrap_matrix(control_list, wrapper = nop):
			return ButtonMatrixElement(rows=[map(wrapper, control_list)])

		self._scene_launch_buttons = wrap_matrix(self._scene_launch_buttons)
		self._track_stop_buttons = wrap_matrix(self._track_stop_buttons)
		self._volume_controls = wrap_matrix(self._volume_controls)
		self._arm_buttons = wrap_matrix(self._arm_buttons)
		self._original_solo_buttons = wrap_matrix(self._original_solo_buttons)
		self._original_mute_buttons = wrap_matrix(self._original_mute_buttons)
		self._select_buttons = wrap_matrix(self._select_buttons)
		self._device_param_controls = wrap_matrix(self._device_param_controls_raw)
		self._device_bank_buttons = wrap_matrix(self._device_bank_buttons, partial(DeviceBankButtonElement, modifiers=[self._shift_button]))

		self._solo_buttons = self._original_solo_buttons
		self._mute_buttons = self._original_mute_buttons

	

	def _create_detail_view_control(self):
		self._detail_view_toggler = DetailViewCntrlComponent(name='Detail_View_Control', is_enabled=False, layer=Layer(device_clip_toggle_button=self._device_clip_toggle_button, device_nav_left_button=self._detail_left_button, device_nav_right_button=self._detail_right_button))  #detail_toggle_button=self._detail_toggle_button

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

	def _setup_mod(self):
		self.monomodular = get_monomodular(self)
		self.monomodular.name = 'monomodular_switcher'
		self.modhandler = APCModHandler(self)
		self.modhandler.name = 'ModHandler' 
		self.modhandler.layer = Layer(priority = 5,
										grid = self._monomod, 
										nav_up_button = self._up_button, 
										nav_down_button = self._down_button, 
										nav_left_button = self._left_button, 
										nav_right_button = self._right_button,
										shiftlock_button = self._nudge_up_button,
										alt_button = self._nudge_down_button,
										shift_button = self._shift_button)
		self.modhandler.set_device_component(self._device_component)
		self.modhandler.set_enabled(False)
		self._monomod_mode = MonomodModeComponent(self._monomod_mode_update, self)
		self._monomod_mode.name = "Monomod_Mode_Component"
		self._monomod_mode.layer = Layer(priority = 5, mode_toggle = self._detail_toggle_button)
		self._on_shift_value.subject = self._shift_button
	

	@subject_slot('value')
	def _on_shift_value(self, value):
		#self._monomod_mode.set_enabled(value>0)
		self._monomod_mode.set_enabled(value is 0)
		#self.modhandler.is_enabled() and self.modhanlder._shift_value(value)
		if value:
			self.modhandler.set_lock_button(self._detail_toggle_button)
		else:
			self.modhandler.set_lock_button(None)
	

	def _monomod_mode_update(self):
		#self.log_message('mode update: ' + str(self._monomod_mode._mode_index))
		if(self._monomod_mode._mode_index == 0):
			self.flash_status = False
			self.modhandler.set_enabled(False)
			self._monomod.reset()
			self._on_selected_track_changed()		
		elif(self._monomod_mode._mode_index == 1):
			self.flash_status = True
			self._monomod.reset()
			self.modhandler.set_enabled(True)
		self._detail_toggle_button.send_value(self._monomod_mode._mode_index)
	

	"""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, (MonoRingedEncoderElement, MonoEncoderElement)):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))
	

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

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

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

	def update_display(self):
		super(AumPC40, self).update_display()
		self._timer = (self._timer + 1) % 256
		self.flash()
	

	def flash(self):
		if self.flash_status:
			for control, _ in self._monomod.iterbuttons():
				if isinstance(control, MonoButtonElement):
					control.flash(self._timer)
	

	def _make_current_bank_details(self, device_component):
		def _current_bank_details():
			if not self.modhandler.active_mod() is None:
				if self.modhandler.active_mod() and self.modhandler.active_mod()._param_component._device_parent != None:
					bank_name = self.modhandler.active_mod()._param_component._bank_name
					bank = [param._parameter for param in self.modhandler.active_mod()._param_component._params]
					if self.modhandler._alt_value.subject and self.modhandler._alt_value.subject.is_pressed():
						bank = bank[8:]
					#self.log_message('current mod bank details: ' + str(bank_name) + ' ' + str(bank))
					return (bank_name, bank)
				else:
					return DeviceComponent._current_bank_details(device_component)
			else:
				return DeviceComponent._current_bank_details(device_component)
		return _current_bank_details
Example #2
0
class Codec(ControlSurface):
    __module__ = __name__
    __doc__ = " MonoCode controller script "

    def __init__(self, c_instance, *a, **k):
        super(Codec, self).__init__(c_instance, *a, **k)
        self._monomod_version = 'b995'
        self._version_check = 'b995'
        self._host_name = 'Codec'
        self._color_type = 'Monochrome'
        self._link_mixer = LINK_MIXER
        self._hosts = []
        self._linked_script = None
        self._local_ring_control = True
        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
        with self.component_guard():
            #self.local_ring_control(True)
            #self.set_absolute_mode(True)
            self._setup_controls()
            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.set_local_ring_control(1)
            self.song().view.add_selected_track_listener(
                self._update_selected_device)
            self._initialize_code()
            #self._shift_mode.set_mode(0)
            #self._monomod_mode.set_mode(0)
        self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Codec ' +
                         str(self._monomod_version) +
                         ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
        self.show_message('Codec Control Surface Loaded')
        self.request_rebuild_midi_map()

    """script initialization methods"""

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

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

    def _setup_controls(self):
        is_momentary = True
        self._livid = CodecMonoButtonElement(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] = CodecMonoButtonElement(
                    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] = CodecMonoButtonElement(
                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] = CodecMonoButtonElement(
                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._mod_mode_update, self)
        self._monomod_mode.name = 'Monomod_Mode'
        self.set_shift_button(self._livid)
        self._shift_mode = ShiftModeComponent(self._shift_update, self)
        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 = CodecMonomodComponent(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, MonoButtonElement)))
        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.log_message('mod mode: ' +
                                 str(abs(self._monomod_mode._mode_index - 1)))
                self._monomod_mode.set_mode(
                    max(0, min(1, 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()):
            with self.component_guard():
                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, MonoButtonElement):
                    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):
        #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
Example #3
0
class Crate(ControlSurface):
    __module__ = __name__
    __doc__ = " Monomodular controller script for Crate "

    def __init__(self, *a, **k):
        super(Crate, self).__init__(*a, **k)
        self._host_name = 'Crate'
        self._version_check = '1.0'
        self._rgb = 0
        self._timer = 0
        self._touched = 0
        self.flash_status = 1
        with self.component_guard():
            self._setup_monobridge()
            self._setup_controls()
            self._setup_session()
            self._setup_next_buttons()
            self._setup_tempo()
            self._setup_modes()
            self._create_fallback_control_owner()
        self.schedule_message(1, self._open_log)
        self.schedule_message(3, self._initialize_surface)

    def _open_log(self):
        self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) +
                         " " + str(self._version_check) +
                         " log opened =>>>>>>>>>>>>>>>>>>>")
        self.show_message(str(self._host_name) + ' Control Surface Loaded')

    def _initialize_surface(self):
        debug('setting to main mode')
        #self._main_modes.selected_mod = 'Main'
        #self._session.set_enabled(True)

    def port_settings_changed(self):
        debug('port settings changed!')
        self._connected = False
        super(Crate, self).port_settings_changed()

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

    def _with_shift(self, button):
        return ComboElement(button, modifiers=[self._shift_button])

    def _setup_controls(self):
        self._button = [
            CrateButtonElement(True,
                               MIDI_NOTE_TYPE,
                               0,
                               index,
                               name='Button_' + str(index),
                               script=self) for index in range(20)
        ]
        self._track_button = [
            CrateButtonElement(True,
                               MIDI_NOTE_TYPE,
                               0,
                               index + 50,
                               name='Button_' + str(index + 50),
                               script=self) for index in range(6)
        ]
        self._next_button = [
            CrateButtonElement(True,
                               MIDI_NOTE_TYPE,
                               0,
                               index + 60,
                               name='Button_' + str(index + 60),
                               script=self) for index in range(2)
        ]
        self._crate_button = [
            CrateButtonElement(True,
                               MIDI_NOTE_TYPE,
                               0,
                               index + 70,
                               name='Button_' + str(index + 70),
                               script=self) for index in range(3)
        ]
        #self._tempo_slider = EncoderElement(MIDI_CC_TYPE, 0, 0, Live.MidiMap.MapMode.absolute, name = 'Slider')

        self._matrix = ButtonMatrixElement(name='Matrix',
                                           rows=[[self._button[index]]
                                                 for index in range(20)])

        self._left_matrix = ButtonMatrixElement(name='Left_Matrix',
                                                rows=[[self._button[index]]
                                                      for index in range(10)])
        self._right_matrix = ButtonMatrixElement(
            name='Right_Matrix',
            rows=[[self._button[index + 10]] for index in range(10)])

        self._track_select_matrix = ButtonMatrixElement(
            name='Track_Matrix', rows=[self._track_button])

    def _setup_session(self):
        self._left_session = CrateSessionComponent(
            script=self,
            name='Session_Component_A',
            num_tracks=1,
            num_scenes=20,
            autonaming=True,
            is_enabled=False,
            layer=Layer(priority=1,
                        clip_launch_buttons=self._matrix,
                        track_nav_buttons=self._track_select_matrix))
        self._left_session.set_group_track('DECK A')
        self._left_session_zooming = SessionZoomingComponent(
            session=self._left_session)

        self._right_session = CrateSessionComponent(
            script=self,
            name='Session_Component_B',
            num_tracks=1,
            num_scenes=20,
            autonaming=True,
            is_enabled=False,
            layer=Layer(priority=1,
                        clip_launch_buttons=self._matrix,
                        track_nav_buttons=self._track_select_matrix))
        self._right_session.set_group_track('DECK B')
        self._right_session_zooming = SessionZoomingComponent(
            session=self._right_session)

        self._left_set_session = CrateSetSessionComponent(
            script=self,
            name='Session_Component_SETA',
            num_tracks=1,
            num_scenes=10,
            autonaming=True,
            is_enabled=False,
            layer=Layer(priority=1, clip_launch_buttons=self._left_matrix))
        self._left_set_session.set_group_track('SET A')
        self._left_set_session_zooming = SessionZoomingComponent(
            session=self._left_set_session)

        self._right_set_session = CrateSetSessionComponent(
            script=self,
            name='Session_Component_SETB',
            num_tracks=1,
            num_scenes=10,
            autonaming=True,
            is_enabled=False,
            layer=Layer(priority=1, clip_launch_buttons=self._right_matrix))
        self._right_set_session.set_group_track('SET B')
        self._right_set_session_zooming = SessionZoomingComponent(
            session=self._right_set_session)

    def _setup_next_buttons(self):
        self._next_a_button = FireNextClipComponent()
        self._next_a_button.set_track('SET A')
        self._next_a_button.layer = Layer(button=self._next_button[0])

        self._next_b_button = FireNextClipComponent()
        self._next_b_button.set_track('SET B')
        self._next_b_button.layer = Layer(button=self._next_button[1])

    def _setup_tempo(self):
        self._on_tempo_changed.subject = self.song()
        self._on_tempo_changed()

    @subject_slot('value')
    def _on_tempo_slider_value(self, value):
        self.song().tempo = ((value / 127.) * 979.) + 20.

    @subject_slot('tempo')
    def _on_tempo_changed(self, *a, **k):
        debug('on tempo changed:', self.song().tempo)
        new_tempo = self.song().tempo
        #self._on_tempo_slider_value.subject and self._on_tempo_slider_value.subject.send_value(((new_tempo-20)/979)*127)
        self.send_tempo('Tempo ' + str(new_tempo))

    def _setup_modes(self):

        next_buttons = CompoundMode(self._next_a_button, self._next_a_button)
        self._main_modes = ModesComponent(name='MainModes')
        self._main_modes.add_mode('disabled', None)
        self._main_modes.add_mode('left_session',
                                  [self._left_session, next_buttons])
        self._main_modes.add_mode('right_session',
                                  [self._right_session, next_buttons])
        self._main_modes.add_mode(
            'set_session',
            [self._left_set_session, self._right_set_session, next_buttons])
        self._main_modes.layer = Layer(
            priority=6,
            left_session_button=self._crate_button[0],
            right_session_button=self._crate_button[1],
            set_session_button=self._crate_button[2])
        self._main_modes.selected_mode = 'set_session'
        self._main_modes.set_enabled(True)

        #self._next_a_button.set_enabled(True)
        #self._next_b_button.set_enabled(True)

    def _create_fallback_control_owner(self):
        self.register_disconnectable(
            SimpleLayerOwner(layer=Layer(_matrix=self._matrix, priority=0)))

    def update_display(self):
        super(Crate, self).update_display()
        self._timer = (self._timer + 1) % 256
        self.flash()

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

    @subject_slot('appointed_device')
    def _on_device_changed(self):
        debug('appointed device changed, script')

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

        ret += ' '
        ret = ret.replace(' ', '_')
        assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
        return ret

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

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

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

    def handle_sysex(self, midi_bytes):
        pass

    def disconnect(self):
        self.log_message("<<<<<<<<<<<<<<<<<<<<<<<<< " + str(self._host_name) +
                         " log closed >>>>>>>>>>>>>>>>>>>>>>>>>")
        super(Crate, self).disconnect()

    def handle_sysex(self, midi_bytes):
        #debug('sysex: ', str(midi_bytes))
        pass

    def clip_name(self, sender, name):
        offset = self._button.index(sender)
        shortname = encode_name_to_sysex(name)
        display_sysex = (240, 0, 0, 102, 1,
                         offset) + tuple(shortname) + (247, )
        self._do_send_midi(display_sysex)

    def track_name(self, offset, name):
        shortname = encode_name_to_sysex(name)
        display_sysex = (240, 0, 0, 102, 2,
                         offset) + tuple(shortname) + (247, )
        self._do_send_midi(display_sysex)

    def send_tempo(self, tempo):
        shortname = encode_name_to_sysex(tempo)
        display_sysex = (
            240,
            0,
            0,
            102,
            3,
        ) + tuple(shortname) + (247, )
        self._do_send_midi(display_sysex)


#	a
Example #4
0
class Alias(ControlSurface):
    __module__ = __name__
    __doc__ = " Alias 8 controller script "

    def __init__(self, c_instance):
        super(Alias, self).__init__(c_instance)
        with self.component_guard():
            self._host_name = 'Alias'
            self._color_type = 'OhmRGB'
            self.log_message(
                "--------------= Alias log opened =--------------")
            self._rgb = 0
            self._timer = 0
            self.flash_status = 1
            self._clutch_device_selection = False
            self._touched = 0
            self._update_linked_device_selection = None
            self._setup_monobridge()
            self._setup_controls()
            self._setup_m4l_interface()
            self._setup_mixer_control()
            self._setup_session_control()
            self._setup_mixer_nav()

    """script initialization methods"""

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

    def _setup_controls(self):
        is_momentary = True
        self._fader = [
            MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, ALIAS_FADERS[index],
                               Live.MidiMap.MapMode.absolute,
                               'Fader_' + str(index), index, self)
            for index in range(9)
        ]
        self._button = [
            MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                              ALIAS_BUTTONS[index], 'Button_' + str(index),
                              self) for index in range(16)
        ]
        self._dial = [
            MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, ALIAS_DIALS[index],
                               Live.MidiMap.MapMode.absolute,
                               'Dial_' + str(index), index + 8, self)
            for index in range(16)
        ]
        self._encoder = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL,
                                           ALIAS_ENCODER,
                                           Live.MidiMap.MapMode.absolute,
                                           'Encoder', 0, self)

    def _setup_m4l_interface(self):
        self._m4l_interface = M4LInterfaceComponent(
            controls=self.controls, component_guard=self.component_guard)
        self.get_control_names = self._m4l_interface.get_control_names
        self.get_control = self._m4l_interface.get_control
        self.grab_control = self._m4l_interface.grab_control
        self.release_control = self._m4l_interface.release_control

    def _setup_mixer_control(self):
        is_momentary = True
        self._num_tracks = (8)  #A mixer is one-dimensional;
        self._mixer = AliasMixerComponent(8, 0, False, False)
        self._mixer.name = 'Mixer'
        self._mixer.set_track_offset(
            0)  #Sets start point for mixer strip (offset from left)
        for index in range(8):
            self._mixer.channel_strip(index).set_volume_control(
                self._fader[index])
            self._mixer.channel_strip(index).set_send_controls(
                tuple([self._dial[index], self._dial[index + 8]]))
            self._mixer.channel_strip(index).set_mute_button(
                self._button[index])
            self._button[index].set_on_off_values(MUTE_TOG, 0)
            self._mixer.channel_strip(index)._invert_mute_feedback = True
            self._mixer.channel_strip(index).set_arm_button(
                self._button[index + 8])
            self._button[index + 8].set_on_off_values(REC_TOG, 0)
            self._mixer.channel_strip(
                index).name = 'Mixer_ChannelStrip_' + str(index)
        self._mixer.master_strip().set_volume_control(self._fader[8])
        self.song().view.selected_track = self._mixer.channel_strip(0)._track

    def _setup_session_control(self):
        self._session = SessionComponent(8, 1)
        self._session.set_mixer(self._mixer)
        self.set_highlighting_session_component(self._session)

    def _setup_mixer_nav(self):
        if not self._encoder.value_has_listener(self._nav_change):
            self._encoder.add_value_listener(self._nav_change)

    """shift/zoom methods"""

    def _nav_change(self, value):
        self._session.set_offsets(
            int((float(value) / float(127)) *
                max(8,
                    len(self._mixer.tracks_to_use()) - 8)),
            self._session._scene_offset)

    """called on timer"""

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

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

    """m4l bridge"""

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

        ret += ' '
        ret = ret.replace(' ', '_')
        assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
        return ret

    def notification_to_bridge(self, name, value, sender):
        if isinstance(sender, MonoEncoderElement):
            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)

    """general functionality"""

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

    def disconnect(self):
        if self._encoder.value_has_listener(self._nav_change):
            self._encoder.remove_value_listener(self._nav_change)
        self.log_message("--------------= Alias log closed =--------------")
        super(Alias, self).disconnect()
        rebuild_sys()

    def handle_sysex(self, midi_bytes):
        pass

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

    def assign_alternate_mappings(self):
        pass

    def _get_num_tracks(self):
        return self.num_tracks

    def _on_device_changed(self, device):
        #self.log_message('new device ' + str(type(device)))
        if self._update_linked_device_selection != None:
            self._update_linked_device_selection(device)

    def _on_session_offset_changes(self):
        if self._r_function_mode._mode_index in range(0, 3):
            self._mem[int(self._r_function_mode._mode_index
                          )] = self._session2.track_offset()

    def connect_script_instances(self, instanciated_scripts):
        pass


#	a
Example #5
0
 def _setup_monobridge(self):
     self._monobridge = MonoBridgeElement(self)
     self._monobridge.name = 'MonoBridge'
Example #6
0
class DS1(ControlSurface):
    __module__ = __name__
    __doc__ = " DS1 controller script "

    def __init__(self, c_instance):
        super(DS1, self).__init__(c_instance)
        self._connected = False
        self._host_name = "DS1"
        self.oscServer = None
        self._rgb = 0
        self._timer = 0
        self.flash_status = 1
        self._touched = 0
        self._update_linked_device_selection = None
        self._skin = Skin(DS1Colors)
        with self.component_guard():
            self._setup_monobridge()
            self._setup_controls()
            self._setup_m4l_interface()
            self._define_sysex()
            self._initialize_hardware()
            self._setup_mixer_control()
            self._setup_session_control()
            self._setup_transport_control()
            self._setup_device_control()
            self._setup_session_recording_component()
            # self._setup_translations()
            self._setup_main_modes()
            # self._device.add_device_listener(self._on_new_device_set)
        self.log_message("<<<<<<<<<<<<<<<<<= DS1 log opened =>>>>>>>>>>>>>>>>>>>>>")
        # self.schedule_message(3, self._initialize_hardware)

    """script initialization methods"""

    def _initialize_hardware(self):
        self.local_control_off.enter_mode()
        self.encoder_absolute_mode.enter_mode()
        self.encoder_speed_sysex.enter_mode()

    def _check_connection(self):
        if not self._connected:
            self._send_midi(QUERYSURFACE)
            self.schedule_message(100, self._check_connection)

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

    def _setup_controls(self):
        is_momentary = True
        self._fader = [
            MonoEncoderElement(
                MIDI_CC_TYPE,
                CHANNEL,
                DS1_FADERS[index],
                Live.MidiMap.MapMode.absolute,
                "Fader_" + str(index),
                index,
                self,
            )
            for index in range(8)
        ]
        for fader in self._fader:
            fader._mapping_feedback_delay = -1
        self._dial = [
            [
                MonoEncoderElement(
                    MIDI_CC_TYPE,
                    CHANNEL,
                    DS1_DIALS[x][y],
                    Live.MidiMap.MapMode.absolute,
                    "Dial_" + str(x) + "_" + str(y),
                    x + (y * 5),
                    self,
                )
                for x in range(8)
            ]
            for y in range(5)
        ]
        for row in self._dial:
            for dial in row:
                dial._mapping_feedback_delay = -1
        self._side_dial = [
            MonoEncoderElement(
                MIDI_CC_TYPE, CHANNEL, DS1_SIDE_DIALS[x], Live.MidiMap.MapMode.absolute, "Side_Dial_" + str(x), x, self
            )
            for x in range(4)
        ]
        for dial in self._side_dial:
            dial._mapping_feedback_delay = -1
        self._encoder = [
            MonoEncoderElement(
                MIDI_CC_TYPE, CHANNEL, DS1_ENCODERS[x], Live.MidiMap.MapMode.absolute, "Encoder_" + str(x), x, self
            )
            for x in range(4)
        ]
        for encoder in self._encoder:
            encoder._mapping_feedback_delay = -1
        self._encoder_button = [
            MonoButtonElement(
                is_momentary,
                MIDI_NOTE_TYPE,
                CHANNEL,
                DS1_ENCODER_BUTTONS[index],
                "EncoderButton_" + str(index),
                self,
                skin=self._skin,
            )
            for index in range(4)
        ]
        self._master_fader = MonoEncoderElement(
            MIDI_CC_TYPE, CHANNEL, DS1_MASTER, Live.MidiMap.MapMode.absolute, "MasterFader", 0, self
        )
        self._button = [
            MonoButtonElement(
                is_momentary, MIDI_NOTE_TYPE, CHANNEL, DS1_BUTTONS[index], "Button_" + str(index), self, skin=self._skin
            )
            for index in range(16)
        ]
        self._grid = [
            [
                MonoButtonElement(
                    is_momentary,
                    MIDI_NOTE_TYPE,
                    CHANNEL,
                    DS1_GRID[x][y],
                    "Button_" + str(x) + "_" + str(y),
                    self,
                    skin=self._skin,
                )
                for x in range(3)
            ]
            for y in range(3)
        ]
        self._dummy = [
            MonoEncoderElement(
                MIDI_CC_TYPE, CHANNEL, 120 + x, Live.MidiMap.MapMode.absolute, "Dummy_Dial_" + str(x), x, self
            )
            for x in range(5)
        ]

        self._fader_matrix = ButtonMatrixElement(name="FaderMatrix", rows=[self._fader])
        self._top_buttons = ButtonMatrixElement(name="TopButtonMatrix", rows=[self._button[:8]])
        self._bottom_buttons = ButtonMatrixElement(name="BottomButtonMatrix", rows=[self._button[8:]])
        self._dial_matrix = ButtonMatrixElement(name="DialMatrix", rows=self._dial)
        self._side_dial_matrix = ButtonMatrixElement(name="SideDialMatrix", rows=[self._side_dial])
        self._encoder_matrix = ButtonMatrixElement(name="EncoderMatrix", rows=[self._encoder])
        self._encoder_button_matrix = ButtonMatrixElement(name="EncoderButtonMatrix", rows=[self._encoder_button])
        self._grid_matrix = ButtonMatrixElement(name="GridMatrix", rows=self._grid)
        self._selected_parameter_controls = ButtonMatrixElement(
            name="SelectedParameterControls", rows=[self._dummy + self._encoder[:1] + self._encoder[2:]]
        )

    def _define_sysex(self):
        self._livid_settings = LividSettings(model=16, control_surface=self)
        self.encoder_speed_sysex = SendLividSysexMode(
            livid_settings=self._livid_settings, call="set_encoder_mapping", message=ENCODER_SPEED
        )
        self.encoder_absolute_mode = SendLividSysexMode(
            livid_settings=self._livid_settings, call="set_encoder_encosion_mode", message=[2]
        )
        self.local_control_off = SendLividSysexMode(
            livid_settings=self._livid_settings, call="set_local_control", message=[0]
        )

        self.main_mode_message = DisplayMessageMode(self, "Mute/Solo Mode")
        self.select_mode_message = DisplayMessageMode(self, "Arm/Select Mode")
        self.clip_mode_message = DisplayMessageMode(self, "Launch/Stop Mode")

    def _setup_autoarm(self):
        self._auto_arm = AutoArmComponent(name="Auto_Arm")
        self._auto_arm.can_auto_arm_track = self._can_auto_arm_track

    def _setup_mixer_control(self):
        self._num_tracks = 8
        self._mixer = MixerComponent(num_tracks=8, num_returns=4, invert_mute_feedback=True, auto_name=True)
        self._mixer.name = "Mixer"
        self._mixer.set_track_offset(0)
        self._mixer.master_strip().set_volume_control(self._master_fader)
        self._mixer.set_prehear_volume_control(self._side_dial[3])
        self._mixer.layer = Layer(volume_controls=self._fader_matrix, track_select_dial=self._encoder[1])
        self._strip = [self._mixer.channel_strip(index) for index in range(8)]
        for index in range(8):
            self._strip[index].layer = Layer(parameter_controls=self._dial_matrix.submatrix[index : index + 1, :])
        self._mixer.selected_strip().layer = Layer(parameter_controls=self._selected_parameter_controls)
        self._mixer.master_strip().layer = Layer(parameter_controls=self._side_dial_matrix.submatrix[:3, :])
        self._mixer.main_layer = AddLayerMode(
            self._mixer, Layer(solo_buttons=self._bottom_buttons, mute_buttons=self._top_buttons)
        )
        self._mixer.select_layer = AddLayerMode(
            self._mixer, Layer(arm_buttons=self._bottom_buttons, track_select_buttons=self._top_buttons)
        )
        self.song().view.selected_track = self._mixer.channel_strip(0)._track
        self._mixer.set_enabled(True)

    def _setup_session_control(self):
        self._session = DS1SessionComponent(num_tracks=8, num_scenes=1, auto_name=True, enable_skinning=True)
        self._session.set_offsets(0, 0)
        self._session.set_mixer(self._mixer)
        self._session.layer = Layer(
            track_select_dial=ComboElement(self._encoder[1], modifiers=[self._encoder_button[1]]),
            scene_bank_up_button=self._grid[0][1],
            scene_bank_down_button=self._grid[0][2],
            scene_launch_buttons=self._grid_matrix.submatrix[1:2, 1:2],
        )
        self._session.clips_layer = AddLayerMode(
            self._session, Layer(clip_launch_buttons=self._top_buttons, stop_track_clip_buttons=self._bottom_buttons)
        )
        self.set_highlighting_session_component(self._session)
        self._session._do_show_highlight()

    def _setup_transport_control(self):
        self._transport = DS1TransportComponent()
        self._transport.name = "Transport"
        self._transport.layer = Layer(
            stop_button=self._grid[1][0], play_button=self._grid[0][0], record_button=self._grid[2][0]
        )
        self._transport.set_enabled(True)

    def _setup_device_control(self):
        self._device = DeviceComponent()
        self._device.name = "Device_Component"
        self.set_device_component(self._device)
        self._device_navigator = DeviceNavigator(self._device, self._mixer, self)
        self._device_navigator.name = "Device_Navigator"
        # self._device_selection_follows_track_selection = FOLLOW
        self._device.device_name_data_source().set_update_callback(self._on_device_name_changed)

    def _setup_session_recording_component(self):
        self._clip_creator = ClipCreator()
        self._clip_creator.name = "ClipCreator"
        self._recorder = SessionRecordingComponent(self._clip_creator, ViewControlComponent())
        self._recorder.set_enabled(True)
        self._recorder.layer = Layer(automation_button=self._grid[1][2], record_button=self._grid[2][1])

    def _setup_m4l_interface(self):
        self._m4l_interface = M4LInterfaceComponent(
            controls=self.controls, component_guard=self.component_guard, priority=10
        )
        self._m4l_interface.name = "M4LInterface"
        self.get_control_names = self._m4l_interface.get_control_names
        self.get_control = self._m4l_interface.get_control
        self.grab_control = self._m4l_interface.grab_control
        self.release_control = self._m4l_interface.release_control

    def _setup_translations(self):
        controls = []
        for control in self.controls:
            controls.append(control)
        self._translations = TranslationComponent(controls, 10)
        self._translations.name = "TranslationComponent"
        self._translations.set_enabled(False)

    def _setup_OSC_layer(self):
        self._OSC_id = 0
        if hasattr(__builtins__, "control_surfaces") or (
            isinstance(__builtins__, dict) and "control_surfaces" in __builtins__.keys()
        ):
            for cs in __builtins__["control_surfaces"]:
                if cs is self:
                    break
                elif isinstance(cs, DS1):
                    self._OSC_id += 1

        self._prefix = "/Live/DS1/" + str(self._OSC_id)
        self._outPrt = OSC_OUTPORT
        if not self.oscServer is None:
            self.oscServer.shutdown()
        self.oscServer = RemixNet.OSCServer("localhost", self._outPrt, "localhost", 10001)

    def _setup_main_modes(self):
        self._main_modes = ToggledModesComponent(name="MainModes")
        self._main_modes.add_mode("Main", [self._mixer.main_layer, self.main_mode_message])
        self._main_modes.add_mode("Select", [self._mixer.select_layer, self.select_mode_message])
        self._main_modes.add_mode("Clips", [self._session.clips_layer, self.clip_mode_message])
        self._main_modes.layer = Layer(priority=4, toggle_button=self._grid[2][2])
        self._main_modes.set_enabled(True)
        self._main_modes.selected_mode = "Main"

    def _notify_descriptors(self):
        if OSC_TRANSMIT:
            for pad in self._pad:
                self.oscServer.sendOSC(
                    self._prefix + "/" + pad.name + "/lcd_name/", str(self.generate_strip_string(pad._descriptor))
                )
            for touchpad in self._touchpad:
                self.oscServer.sendOSC(
                    self._prefix + "/" + touchpad.name + "/lcd_name/",
                    str(self.generate_strip_string(touchpad._descriptor)),
                )
            for button in self._button:
                self.oscServer.sendOSC(
                    self._prefix + "/" + button.name + "/lcd_name/", str(self.generate_strip_string(button._descriptor))
                )

    def _get_devices(self, track):
        def dig(container_device):
            contained_devices = []
            if container_device.can_have_chains:
                for chain in container_device.chains:
                    for chain_device in chain.devices:
                        for item in dig(chain_device):
                            contained_devices.append(item)
            else:
                contained_devices.append(container_device)
            return contained_devices

        devices = []
        for device in track.devices:
            for item in dig(device):
                devices.append(item)
                # self.log_message('appending ' + str(item))
        return devices

    """called on timer"""

    def update_display(self):
        super(DS1, self).update_display()
        self._timer = (self._timer + 1) % 256
        self.flash()

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

    """m4l bridge"""

    def _on_device_name_changed(self):
        name = self._device.device_name_data_source().display_string()
        self._monobridge._send("Device_Name", "lcd_name", str(self.generate_strip_string("Device")))
        self._monobridge._send("Device_Name", "lcd_value", str(self.generate_strip_string(name)))
        self.touched()
        if OSC_TRANSMIT:
            self.oscServer.sendOSC(self._prefix + "/glob/device/", str(self.generate_strip_string(name)))

    def _on_device_bank_changed(self):
        name = "No Bank"
        if is_device(self._device._device):
            name, _ = self._device._current_bank_details()
        self._monobridge._send("Device_Bank", "lcd_name", str(self.generate_strip_string("Bank")))
        self._monobridge._send("Device_Bank", "lcd_value", str(self.generate_strip_string(name)))
        self.touched()

    def _on_device_chain_changed(self):
        name = " "
        if (
            is_device(self._device._device)
            and self._device._device.canonical_parent
            and isinstance(self._device._device.canonical_parent, Live.Chain.Chain)
        ):
            name = self._device._device.canonical_parent.name
        self._monobridge._send("Device_Chain", "lcd_name", str(self.generate_strip_string("Chain")))
        self._monobridge._send("Device_Chain", "lcd_value", str(self.generate_strip_string(name)))
        self.touched()

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

        ret += " "
        ret = ret.replace(" ", "_")
        assert len(ret) == NUM_CHARS_PER_DISPLAY_STRIP
        return ret

    def notification_to_bridge(self, name, value, sender):
        # self.log_message('monobridge:' + str(name) + str(value))
        if isinstance(sender, MonoEncoderElement):
            if OSC_TRANSMIT:
                self.oscServer.sendOSC(
                    self._prefix + "/" + sender.name + "/lcd_name/", str(self.generate_strip_string(name))
                )
                self.oscServer.sendOSC(
                    self._prefix + "/" + sender.name + "/lcd_value/", str(self.generate_strip_string(value))
                )
            self._monobridge._send(sender.name, "lcd_name", str(self.generate_strip_string(name)))
            self._monobridge._send(sender.name, "lcd_value", str(self.generate_strip_string(value)))
        else:
            self._monobridge._send(name, "lcd_name", str(self.generate_strip_string(name)))
            self._monobridge._send(name, "lcd_value", str(self.generate_strip_string(value)))
            if OSC_TRANSMIT:
                self.oscServer.sendOSC(self._prefix + "/" + name + "/lcd_name/", str(self.generate_strip_string(name)))
                self.oscServer.sendOSC(
                    self._prefix + "/" + name + "/lcd_value/", str(self.generate_strip_string(value))
                )

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

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

    """general functionality"""

    def disconnect(self):
        if not self.oscServer is None:
            self.oscServer.shutdown()
        self.oscServer = None
        self.log_message("--------------= DS1 log closed =--------------")
        super(DS1, self).disconnect()

    def _can_auto_arm_track(self, track):
        routing = track.current_input_routing
        return routing == "Ext: All Ins" or routing == "All Ins" or routing.startswith("DS1 Input")
        # self._main_modes.selected_mode in ['Sends', 'Device'] and

    def _on_selected_track_changed(self):
        super(DS1, self)._on_selected_track_changed()

    def handle_sysex(self, midi_bytes):
        # self.log_message('sysex: ' + str(midi_bytes))
        if len(midi_bytes) > 14:
            if midi_bytes[3:10] == tuple([6, 2, 0, 1, 97, 1, 0]):
                if not self._connected:
                    self._connected = True
                    self._initialize_hardware()
Example #7
0
class BlockMod(MonOhm):
	__module__ = __name__
	__doc__ = " Monomodular controller script for Livid Block "


	def __init__(self, *a, **k):
		self._shift_button = None
		super(BlockMod, self).__init__(*a, **k)
		self._host_name = 'BlockMod'
		self._color_type = 'Monochrome'
		self._link_mixer = LINK_MIXER
		self._rgb = 1
		self._ohm = 127
		self._ohm_type = 'static'
		self._pad_translations = PAD_TRANSLATION
		self._mem = [4, 8, 12, 16]
		self.modhandler._color_type = 'Monochrome'
	

	"""script initialization methods"""
	def _setup_monobridge(self):
		self._monobridge = MonoBridgeElement(self)
		self._monobridge.name = 'MonoBridge'
	

	def _setup_controls(self):
		is_momentary = True
		self._fader = [None for index in range(8)]
		self._dial = [None for index in range(8)]
		self._button = [None for index in range(8)]
		self._menu = [None for index in range(6)]
		for index in range(2):
			self._fader[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, SLIDER_CC[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self)
		#for index in range(8):
		#	self._button[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self)
		for index in range(8):
			self._dial[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, KNOB_CC[index], Live.MidiMap.MapMode.absolute, 'Dial_' + str(index), index + 8, self)
		for index in range(4):
			self._menu[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, FUNCTION_NOTES[index], 'Menu_' + str(index), self)	
		#self._livid = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		self._livid = DoublePressElement(MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self))
		self._shift_l = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Shift_Button_Left', self)
		self._shift_r = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Shift_Button_Right', self)
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		self._grid = [None for index in range(8)]
		for column in range(8):
			self._grid[column] = [None for index in range(8)]
			for row in range(8):
				self._grid[column][row] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (column * 8) + row, 'Grid_' + str(column) + '_' + str(row), self)
		for row in range(5):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])
			self._matrix.add_row(tuple(button_row)) 
		for row in range(8):
			button_row = []
			for column in range(8):
				button_row.append(self._grid[column][row])
			self._monomod.add_row(tuple(button_row))
		self._dummy_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 125)
		self._dummy_button.name = 'Dummy1'
		self._dummy_button2 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 126)
		self._dummy_button2.name = 'Dummy2'
		self._dummy_button3 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 127)
		self._dummy_button2.name = 'Dummy3'
		self._dial_matrix = ButtonMatrixElement()
		self._dial_matrix.add_row(self._dial)
	

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

	def _setup_crossfader(self):
		pass
	

	def _setup_mod(self):
		super(BlockMod, self)._setup_mod()
		self.modhandler.nav_box.on_value = 8
	

	def _setup_layers(self):
		self._device_navigator.layer = Layer(priority = 5, prev_button = self._menu[2], next_button = self._menu[3])
		self._device.mod_layer = AddLayerMode(self._device, Layer(priority = 5, bank_prev_button = self._menu[0], bank_next_button = self._menu[1]))
		self._transport.mod_layer = AddLayerMode(self._transport, Layer(priority = 5, play_button = self._menu[2], stop_button = self._menu[3]))
		self.modhandler.set_mod_button(self._livid)
		self.modhandler.layer = Layer(priority = 5, 
									grid = self._monomod,
									nav_up_button = self._menu[0],
									nav_down_button = self._menu[1],
									nav_left_button = self._menu[2],
									nav_right_button =  self._menu[3],
									shift_button = self._shift_r,
									alt_button = self._shift_l,
									parameter_controls = self._dial_matrix)
		self.modhandler.legacy_shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6,
									channel_buttons = self._monomod.submatrix[:, 1:2],
									nav_matrix = self._monomod.submatrix[:4, 2:6]))
		self.modhandler.shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6, 
									lock_button = self._livid,
									device_selector_matrix = self._monomod.submatrix[:, :1],
									key_buttons = self._monomod.submatrix[:, 7:8]))
		self.modhandler.shiftlock_mode = AddLayerMode(self.modhandler, Layer(priority = 6, 
									key_buttons = self._monomod.submatrix[:, 7:8]))
	

	def _setup_modes(self):
		self._monomod_mode = MonomodModeComponent(self, self.monomod_mode_update)
		self._monomod_mode.name = 'Monomod_Mode'
		self._monomod_mode.layer = Layer(priority = 5, mode_toggle = self._livid)
		self._monomod_mode.set_enabled(True)
		self._on_shift_doublepress_value.subject = self._livid.double_press
		self._shift_mode = BlockModShiftModeComponent(self, self.shift_update) 
		self._shift_mode.name = 'Shift_Mode'
		#self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r)
		self._shift_mode.layer = Layer(priority = 3, toggle1 = self._shift_l, toggle2 = self._shift_r)
		self._shift_mode.set_enabled(True)
		self._l_function_mode = FunctionModeComponent(self, self.l_function_update)
		self._l_function_mode.name = 'Left_Function_Mode'
		self._r_function_mode = FunctionModeComponent(self, self.r_function_update)
		self._r_function_mode.name = 'Right_Function_Mode'
		self._m_function_mode = FunctionModeComponent(self, self.m_function_update)
		self._m_function_mode.name = 'Main_Function_Mode'
		self._function_modes = [self._l_function_mode, self._r_function_mode, self._m_function_mode]
	

	@subject_slot('value')
	def _on_shift_doublepress_value(self, value):
		#self._monomod_mode.set_mode(abs(self._monomod_mode._mode_index -1))
		pass
	

	"""shift/zoom methods"""
	def deassign_matrix(self):
		self._session_zoom.set_button_matrix(None)
		self._session_zoom2.set_button_matrix(None)
		#self._session.set_stop_track_clip_buttons(None)
		#self._session2.set_stop_track_clip_buttons(None)
		self._session_zoom_main.set_button_matrix(None)
		#self._session_main.set_stop_track_clip_buttons(None)
		for column in range(4):
			self._mixer2.channel_strip(column).set_select_button(None)
			self._mixer2.return_strip(column).set_mute_button(None)
			self._mixer2.return_strip(column).set_solo_button(None)
			self._mixer2.return_strip(column).set_arm_button(None)
			self._mixer2.return_strip(column).set_crossfade_toggle(None)
			self._mixer2.return_strip(column).set_select_button(None)			#shouldn't this be somewhere else?
			self._mixer2.channel_strip(column).set_crossfade_toggle(None)
			self._mixer2.channel_strip(column).set_mute_button(None)
			self._mixer2.channel_strip(column).set_solo_button(None)
			self._mixer2.channel_strip(column).set_arm_button(None)
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(None)
				self._scene2[row].clip_slot(column).set_launch_button(None)
		for index in range(5):
			self._scene[index].set_launch_button(None)
			self._scene2[index].set_launch_button(None)
			self._scene_main[index].set_launch_button(None)
		self._session_zoom.set_nav_buttons(None, None, None, None)
		self._session_zoom2.set_nav_buttons(None, None, None, None)
		self._session_zoom_main.set_nav_buttons(None, None, None, None)
		self._session.set_track_bank_buttons(None, None)
		self._session.set_scene_bank_buttons(None, None)
		self._session2.set_track_bank_buttons(None, None)
		self._session2.set_scene_bank_buttons(None, None)
		self._session_main.set_track_bank_buttons(None, None)
		self._session_main.set_scene_bank_buttons(None, None)
		for column in range(8):
			self._mixer.channel_strip(column).set_select_button(None)
			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)
			for row in range(5):
				self._scene_main[row].clip_slot(column).set_launch_button(None)
			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].set_on_off_values(127, 0)
				self._grid[column][row].send_value(0, True)
		#self._send_reset.set_buttons(tuple(None for index in range(4)))
	

	def zoom_off(self):
		for column in range(4):
			self._grid[column][5].set_on_value(MUTE[self._rgb])
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6].set_on_value(ARM[self._rgb])
			self._mixer.channel_strip(column).set_arm_button(self._grid[column][6])
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
			if(self._r_function_mode._mode_index in range(0,3)):
				self._grid[column + 4][5].set_on_value(MUTE[self._rgb])
				self._mixer2.channel_strip(column).set_mute_button(self._grid[column + 4][5])
				self._grid[column + 4][6].set_on_value(ARM[self._rgb])
				self._mixer2.channel_strip(column).set_arm_button(self._grid[column + 4][6])
				for row in range(5):
					self._scene2[row].clip_slot(column).set_launch_button(self._grid[column + 4][row])
			elif(self._r_function_mode._mode_index is 3):
				self._grid[column + 4][5].set_on_value(MUTE[self._rgb])
				self._mixer2.return_strip(column).set_mute_button(self._grid[column + 4][5])
				for row in range(5):
					self._grid[column + 4][row].send_value(USER1_COLOR[self._rgb], True)
					self._grid[column + 4][row].set_channel(RIGHT_USER1_CHANNEL)
					self._grid[column + 4][row].set_identifier(RIGHT_USER1_MAP[column][row])
					self._grid[column + 4][row].set_enabled(False)	 #this has to happen for translate to work
				#self._session_zoom2.set_ignore_buttons(True)
		if(self._r_function_mode._mode_index is 0):
			for index in range(4):
				self._grid[index + 4][7].send_value(SEND_RESET[self._rgb], True)
			#self._send_reset.set_buttons(tuple(self._grid[index + 4][7] for index in range(4)))
	

	def zoom_off_m(self):
		self.deassign_dials()
		for column in range(8):
			self._grid[column][5].set_on_value(MUTE[self._rgb])
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6].set_on_value(ARM[self._rgb])
			self._mixer.channel_strip(column).set_arm_button(self._grid[column][6])
			for row in range(5):
				self._scene_main[row].clip_slot(column).set_launch_button(self._grid[column][row])
		#self._session_zoom.set_button_matrix(self._matrix)
	

	def zoom_left(self):
		track_stop_buttons = []
		track_stop_buttons2 = []
		for index in range(4):
			self._grid[index][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
			self._grid[index + 4][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons2.append(self._grid[index + 4][6])
		for index in range(5):
			self._grid[7][index].set_off_value(SCENE_LAUNCH[self._rgb])
			self._scene[index].set_launch_button(self._grid[7][index])
		#self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		#self._session.set_stop_track_clip_buttons(self._matrix.submatrix[:4][7:])
		#self._session2.set_stop_track_clip_buttons(tuple(track_stop_buttons2))
		#self._session2.set_stop_track_clip_buttons(self._matrix.submatrix[4:8][7:])
		self._session_zoom.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])	
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		#self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index + 4][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.set_matrix(self._monomod.submatrix[4:8][7:])
		self._device_selector.set_offset(4)
	

	def zoom_right(self):
		track_stop_buttons = []
		track_stop_buttons2 = []
		for index in range(4):
			self._grid[index][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
		for index in range(5):
			self._grid[7][index].set_off_value(SCENE_LAUNCH[self._rgb])
			self._scene2[index].set_launch_button(self._grid[7][index])
		#self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		#self._session.set_stop_track_clip_buttons(self._matrix.submatrix[:4][7:])
		if(self._r_function_mode._mode_index < 3):
			for index in range(4):
				self._grid[index + 4][6].set_off_value(TRACK_STOP[self._rgb])
				track_stop_buttons2.append(self._grid[index + 4][6])
			#self._session2.set_stop_track_clip_buttons(self._matrix.submatrix[4:8][7:])
			#self._session2.set_stop_track_clip_buttons(tuple(track_stop_buttons2))
		self._session_zoom2.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		#self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.set_matrix(self._monomod.submatrix[:4][7:])
		self._device_selector.set_offset(0)
	

	def zoom_main(self):
		track_stop_buttons = []
		for index in range(8):
			self._grid[index][6].set_on_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
		for index in range(5):
			self._grid[7][index].set_on_value(SCENE_LAUNCH[self._rgb])
			self._scene_main[index].set_launch_button(self._grid[7][index])
		#self._session_main.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		#self._session_main.set_stop_track_clip_buttons(self._matrix[0:8][7:])
		self._session_zoom_main.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])	
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		#self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index + 4][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.set_matrix(self._monomod.submatrix[4:8][7:])
		self._device_selector.set_offset(4)
	


	"""function mode callbacks"""
	def l_function_update(self):
		mode = self._l_function_mode._mode_index
		if(self._l_function_mode.is_enabled() is False):
			self._l_function_mode.set_mode_buttons(None)
		if not self.modhandler.is_enabled():
			if(self._l_function_mode.is_enabled() is True):
				if(len(self._l_function_mode._modes_buttons) is 0):
					for index in range(4):
						self._mixer.channel_strip(index).set_select_button(None)
					buttons = []
					for index in range(4):
						buttons.append(self._grid[index][7]) 
					self._l_function_mode.set_mode_buttons(tuple(buttons))
				if(self._shift_mode._mode_index is 2):
					for index in range(4):
						if(mode != index):
							self._grid[index][7].turn_off()
						else:
							self._grid[index][7].turn_on()
			if(mode is 0):
				self.assign_device_dials()
				self.show_message('Mixer Split:Dials Device Mode')
			elif(mode is 1):
				self.assign_send_dials()
				self.show_message('Mixer Split:Dials Send Mode')
			elif(mode is 2):
				self.assign_split_volume_dials()
				self.show_message('Mixer Split:Dials Volume Mode')
			elif(mode is 3):
				self.assign_user_dials()
				self.show_message('Mixer Split:Dials User Map Mode')
	

	def r_function_update(self):
		mode = self._r_function_mode._mode_index
		if(self._r_function_mode.is_enabled() is False):
			self._r_function_mode.set_mode_buttons(None)
			#self._session2.set_show_highlight(False)
			#self._session._highlighting_callback(self._session._track_offset, self._session._scene_offset, 4, 5, 1)
		if not self.modhandler.is_enabled():
			if(self._r_function_mode.is_enabled() is True):
				if(len(self._r_function_mode._modes_buttons) is 0):
					for index in range(4):
						self._mixer2.channel_strip(index).set_select_button(None)
					buttons = []
					for index in range(4):
						buttons.append(self._grid[index + 4][7]) 
					self._r_function_mode.set_mode_buttons(tuple(buttons))
				if(self._shift_mode._mode_index is 3):
					for index in range(4):
						if(mode != index):
							self._grid[index + 4][7].turn_off()
						else:
							self._grid[index + 4][7].turn_on()
			self._session2.set_offsets(int(self._mem[mode]), self._session2._scene_offset)
			self.show_message('Mixer Split: Track Offset' + str(RIGHT_MODE_OFFSETS[mode]))
	

	def m_function_update(self):
		mode = self._m_function_mode._mode_index
		if(self._m_function_mode.is_enabled() is False):
			self._m_function_mode.set_mode_buttons(None)
			#self._session.set_show_highlight(False)
			#self._session2.set_show_highlight(False)
			#self._session_main._highlighting_callback(self._session_main._track_offset, self._session_main._scene_offset, 8, 5, 1)
		if not self.modhandler.is_enabled():
			if(self._m_function_mode.is_enabled() is True):
				if(len(self._m_function_mode._modes_buttons) is 0):
					for index in range(8):
						self._mixer.channel_strip(index).set_select_button(None)
					buttons = []
					for index in range(4):
						buttons.append(self._grid[index][7]) 
					self._m_function_mode.set_mode_buttons(tuple(buttons))
				if(self._shift_mode._mode_index is 4):
					for index in range(4):
						if(mode != index):
							self._grid[index][7].turn_off()
						else:
							self._grid[index][7].turn_on()
			if(mode is 0):
				self.assign_device_dials()
				self.show_message('Mixer Linked:Dials Device Mode')
			elif(mode is 1):
				self.assign_send_dials()
				self.show_message('Mixer Linked:Dials Send Mode')
			elif(mode is 2):
				self.assign_volume_dials()
				self.show_message('Mixer Linked:Dials Volume Mode')
			elif(mode is 3):
				self.assign_user_dials()
				self.show_message('Mixer Linked:Dials User Map Mode')
	

	def shift_update(self):
		self._clutch_device_selection = True
		#self.allow_updates(False)
		#if(not self._in_build_midi_map):
		#	self.set_suppress_rebuild_requests(True)
		self.deassign_channel_select_buttons()
		self.deassign_matrix()
		self.deassign_menu()
		if(self._monomod_mode._mode_index is 0):		#if monomod is not on
			if(self._shift_mode._mode_index is 0):							#if no shift is pressed
				#self._shift_mode._mode_toggle1.turn_off()
				#self._shift_mode._mode_toggle2.turn_off()
				if(self.split_mixer() is False):
					self.set_split_mixer(True)
				for zoom in self._zooms:
					zoom._on_zoom_value(0)
				self.zoom_off()
				self._device_selector.set_enabled(False)
				for mode in self._function_modes:
					mode.set_enabled(False)
				self.assign_channel_select_buttons()
				#self._recalculate_selected_channel()
				#self.assign_transport_to_menu()
				self.assign_session_nav_to_menu()
				self.l_function_update()
				self.r_function_update()
				self.assign_crossfader()
				self.set_highlighting_session_component(self._session)
				self._session._do_show_highlight()	
				#self._session.set_show_highlight(True)
			elif(self._shift_mode._mode_index is 1):						#if no shift is pressed, but mixer is linked
				#self._shift_mode._mode_toggle1.turn_on()
				#self._shift_mode._mode_toggle2.turn_on()
				if(self.split_mixer() is True):
					self.set_split_mixer(False)
				for zoom in self._zooms:
					zoom._on_zoom_value(0)
				self.zoom_off_m()
				self._device_selector.set_enabled(False)
				for mode in self._function_modes:
					mode.set_enabled(False)
				self.assign_main_channel_select_buttons()
				self.assign_session_main_nav_to_menu()
				self.m_function_update()
				self.assign_crossfader()
				self.set_highlighting_session_component(self._session_main)
				self._session_main._do_show_highlight()
			elif(self._shift_mode._mode_index > 1):						#if a shift is pressed
				self.assign_device_nav_to_menu()
				self.deassign_channel_select_buttons()
				if(self._shift_mode._mode_index is 2):					#if shift left
					#self._shift_mode._mode_toggle1.turn_on()
					self.zoom_left()
					self._session_zoom._on_zoom_value(1)
					self._session.set_enabled(True) #this is a workaround so that the stop buttons still function
					self._l_function_mode.set_enabled(True)
					self.set_highlighting_session_component(self._session)
					self._session._do_show_highlight()
				elif(self._shift_mode._mode_index is 3):				#if shift right
					#self._shift_mode._mode_toggle2.turn_on()
					self.zoom_right()
					self._session_zoom2._on_zoom_value(1)
					self._session2.set_enabled(True)  #this is a workaround so that the stop buttons still function
					self._r_function_mode.set_enabled(True)
					self.assign_master_fader()
					if(self._r_function_mode._mode_index < 4):
						self.set_highlighting_session_component(self._session2)
						self._session2._do_show_highlight()
				elif(self._shift_mode._mode_index is 4):				#if either shift pressed while mixer is linked
					#self._shift_mode._mode_toggle1.turn_on()
					#self._shift_mode._mode_toggle2.turn_on()
					self.zoom_main()
					self._session_zoom_main._on_zoom_value(1)
					self._session_main.set_enabled(True) #this is a workaround so that the stop buttons still function
					self._m_function_mode.set_enabled(True)
					self.assign_master_fader()
					self.set_highlighting_session_component(self._session_main)
					self._session_main._do_show_highlight()
				self._device_selector.set_enabled(True)
		else:
			for mode in self._function_modes:
				mode.set_enabled(False)
			#self.modhandler._shift_value(int(self._shift_mode._mode_index>1))
		self.allow_updates(True)
		#self.set_suppress_rebuild_requests(False)
		self._clutch_device_selection = False
		if(self._shift_mode._mode_index < 2):
			self._monobridge._send('touch', 'off')
		else:
			self._monobridge._send('touch', 'on')
	

	"""left control management methods"""
	def deassign_dials(self):
		for index in range(8):
			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._mixer.selected_strip().set_send_controls(None)
		self._mixer.selected_strip().set_volume_control(None)
		for track in range(4):
			self._mixer.channel_strip(track).set_volume_control(None)
			self._mixer.channel_strip(track+4).set_volume_control(None)
			self._mixer2.channel_strip(track).set_volume_control(None)
			self._mixer2.return_strip(track).set_volume_control(None)
	

	def assign_device_dials(self):
		self._ohm_type = OHM_TYPE[0]
		self._ohm = OHM_VALUE[0]
		self.deassign_dials()
		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._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_send_dials(self):
		self._ohm_type = OHM_TYPE[1]
		self._ohm = OHM_VALUE[1]
		self.deassign_dials()
		dials = []
		for index in range(4):
			dials.append(self._dial[index])
		for index in range(4):
			if(self._mixer2.return_strip(index)):
				self._mixer2.return_strip(index).set_volume_control(self._dial[index + 4])
		self._mixer.selected_strip().set_send_controls(tuple(dials))
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_volume_dials(self):
		self._ohm_type = OHM_TYPE[2]
		self._ohm = OHM_VALUE[2]
		self.deassign_dials()
		for track in range(8):
			self._mixer.channel_strip(track).set_volume_control(self._dial[track])
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_split_volume_dials(self):
		self._ohm_type = OHM_TYPE[2]
		self._ohm = OHM_VALUE[2]
		self.deassign_dials()
		for track in range(4):
			self._mixer.channel_strip(track).set_volume_control(self._dial[track])
			self._mixer2.channel_strip(track).set_volume_control(self._dial[track+4])
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_user_dials(self):
		self._ohm_type = OHM_TYPE[3]
		self._ohm = OHM_VALUE[3]
		self.deassign_dials()
		for index in range(8):
			self._dial[index].set_channel(L_USER_DIAL_CHAN)
			self._dial[index].set_identifier(L_USER_DIAL_MAP[index])
			self._dial[index].set_enabled(False)
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	


	"""menu button management methods"""
	def deassign_menu(self):
		self._device.set_lock_button(None)
		self._device.set_on_off_button(None)
		#self._device_navigator.set_device_nav_buttons(None, None)	
		self._device_navigator.set_enabled(False)
		self._device.set_bank_nav_buttons(None, None)
		self._transport.set_play_button(None)	
		self._transport.set_record_button(None) 
		self._transport.set_stop_button(None)
		self._transport.set_loop_button(None)	
		self._transport.set_overdub_button(None)	
		self._session.set_stop_all_clips_button(None)
		self._session_main.set_track_bank_buttons(None, None)
		self._session_main.set_scene_bank_buttons(None, None)
	

	def assign_device_nav_to_menu(self):
		#self._device_navigator.set_device_nav_buttons(self._menu[2], self._menu[3]) 
		self._device_navigator.set_enabled(True)
		self._device.set_bank_nav_buttons(self._menu[0], self._menu[1])
	

	def assign_transport_to_menu(self):
		self._transport.set_play_button(self._menu[0])	
		self._transport.set_record_button(self._menu[2])
		self._transport.set_stop_button(self._menu[1])
		session.set_stop_all_clips_button(self._menu[3])
	

	def assign_session_nav_to_menu(self):
		self._session.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_monomod_shift_to_menu(self):
		#self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[2])
		self._device_navigator.set_enabled(True)
		self._device.set_bank_nav_buttons(self._menu[1], self._menu[0])
	

	def assign_session_bank_to_menu(self):
		self._session.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_session2_bank_to_menu(self):
		self._session2.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session2.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_session_main_nav_to_menu(self):
		self._session_main.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session_main.set_scene_bank_buttons(self._menu[1], self._menu[0])
	


	"""channel selection management methods"""
	def deassign_channel_select_buttons(self):
		for index in range(8):
			if(self._mixer.channel_strip(index)):
				self._mixer.channel_strip(index).set_select_button(None)
			self._grid[index][7].release_parameter()
		for index in range(4):
			self._mixer2.channel_strip(index).set_select_button(None)
			self._mixer2.return_strip(index).set_select_button(None)
			self._mixer2.master_strip().set_select_button(None)
			self._grid[index + 4][7].release_parameter()
	

	def assign_channel_select_buttons(self):
		for index in range(4):
			#if(self._mixer.channel_strip(index)):
			self._grid[index][7].set_on_off_values(127, 0)
			self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
		if(self._r_function_mode._mode_index < 3):
			for index in range(4):
				self._grid[index][7].set_on_off_values(127, 0)
				self._mixer2.channel_strip(index).set_select_button(self._grid[index + 4][7])	
		else:
			for index in range(4):
				self._grid[index][7].set_on_off_values(1, 0)
				self._mixer2.return_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_return_select_buttons(self):
		for index in range(4):
			self._grid[index + 4][7].set_off_value(0) 
			if(self._mixer.channel_strip(index)):
				self._grid[index + 4][7].set_on_value(1)
				self._mixer.channel_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_l_channel_select_buttons(self):
		self._mixer.set_select_buttons(None, None)
		self._session.set_select_buttons(None, None)
		for index in range(4):
			self._grid[index][7].set_off_value(0)
			if(self._mixer.channel_strip(index)):
				self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
	

	def assign_r_channel_select_buttons(self):
		self._mixer2.set_select_buttons(None, None)
		self._session2.set_select_buttons(None, None)
		for index in range(4):
			self._grid[index + 4][7].set_off_value(0)
			if(self._mixer2.channel_strip(index)):
				self._mixer2.channel_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_main_channel_select_buttons(self):
		for index in range(8):
			self._grid[index][7].set_off_value(0)
			if(self._mixer.channel_strip(index)):
				self._grid[index][7].set_on_value(127)
				self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
	

	def assign_master_fader(self):
		self._mixer.set_crossfader_control(None)
		self._mixer.master_strip().set_volume_control(self._fader[1])
	

	def assign_crossfader(self):
		self._mixer.master_strip().set_volume_control(None)
		self._mixer.set_crossfader_control(self._fader[1])
	


	"""called on timer"""
	def update_display(self):
		super(BlockMod, self).update_display()
		if(self._timer == 0):
			self._shift_pressed_timer = -12
	

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

	def handle_sysex(self, midi_bytes):
		pass
	

	def _on_session_offset_changes(self):
		if self._r_function_mode._mode_index in range(0,4):
			self._mem[int(self._r_function_mode._mode_index)] = self._session2.track_offset()
	



#	a
Example #8
0
class BlockMod(MonOhm):
	__module__ = __name__
	__doc__ = " Monomodular controller script for Livid Block "


	def __init__(self, *a, **k):
		self._shift_button = None
		self._shift_pressed = 0
		self._shift_pressed_timer = 0
		self._shift_thresh = SHIFT_THRESH
		super(BlockMod, self).__init__(*a, **k)
		self._host_name = 'BlockMod'
		self._color_type = 'Monochrome'
		self._link_mixer = LINK_MIXER
		self._rgb = 1
		self._ohm = 127
		self._ohm_type = 'static'
		self._pad_translations = PAD_TRANSLATION
		self._mem = [4, 8, 12, 16]
		self._host._navbox_selected = 8
	

	"""script initialization methods"""
	def _setup_monobridge(self):
		self._monobridge = MonoBridgeElement(self)
		self._monobridge.name = 'MonoBridge'
	

	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(2):
			self._fader[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, SLIDER_CC[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self)
		#for index in range(8):
		#	self._button[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self)
		for index in range(8):
			self._dial[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, KNOB_CC[index], Live.MidiMap.MapMode.absolute, 'Dial_' + str(index), index + 8, self)
		for index in range(4):
			self._menu[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, FUNCTION_NOTES[index], 'Menu_' + str(index), self)	
		self._livid = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		self._shift_l = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Shift_Button_Left', self)
		self._shift_r = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Shift_Button_Right', self)
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		self._grid = [None for index in range(8)]
		for column in range(8):
			self._grid[column] = [None for index in range(8)]
			for row in range(8):
				self._grid[column][row] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (column * 8) + row, 'Grid_' + str(column) + '_' + str(row), self)
		for row in range(5):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])
			self._matrix.add_row(tuple(button_row)) 
		for row in range(8):
			button_row = []
			for column in range(8):
				button_row.append(self._grid[column][row])
			self._monomod.add_row(tuple(button_row))
		self._dummy_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 125)
		self._dummy_button.name = 'Dummy1'
		self._dummy_button2 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 126)
		self._dummy_button2.name = 'Dummy2'
		self._dummy_button3 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 127)
		self._dummy_button2.name = 'Dummy3'
	

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

	def _setup_crossfader(self):
		pass
	

	def _setup_modes(self):
		self._monomod_mode = MonomodModeComponent(self, self.monomod_mode_update)
		self._monomod_mode.name = 'Monomod_Mode'
		self.set_shift_button(self._livid)
		self._shift_mode = BlockModShiftModeComponent(self, self.shift_update) 
		self._shift_mode.name = 'Shift_Mode'
		self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r)
		self._l_function_mode = FunctionModeComponent(self, self.l_function_update)
		self._l_function_mode.name = 'Left_Function_Mode'
		self._r_function_mode = FunctionModeComponent(self, self.r_function_update)
		self._r_function_mode.name = 'Right_Function_Mode'
		self._m_function_mode = FunctionModeComponent(self, self.m_function_update)
		self._m_function_mode.name = 'Main_Function_Mode'
		self._function_modes = [self._l_function_mode, self._r_function_mode, self._m_function_mode]
	


	"""livid double press mechanism"""
	def set_shift_button(self, button):
		assert ((button == None) or (isinstance(button, MonoButtonElement)))
		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:
			if (self._shift_pressed_timer + self._shift_thresh) > self._timer:
				if(self._host._active_client != None):
					if(self._host.is_enabled() != True):
						self._monomod_mode.set_mode(1)
					else:
						self._monomod_mode.set_mode(0)
			else:
				self._shift_pressed_timer = self._timer % 256
			if(self._cntrlr != None):
				self._cntrlr._monohm_shift(2)
		else:
			if(self._cntrlr != None):
				self._cntrlr._monohm_shift(0)
	

	"""shift/zoom methods"""
	def deassign_matrix(self):
		self._session_zoom.set_button_matrix(None)
		self._session_zoom2.set_button_matrix(None)
		self._session.set_stop_track_clip_buttons(None)
		self._session2.set_stop_track_clip_buttons(None)
		self._session_zoom_main.set_button_matrix(None)
		self._session_main.set_stop_track_clip_buttons(None)
		for column in range(4):
			self._mixer2.channel_strip(column).set_select_button(None)
			self._mixer2.return_strip(column).set_mute_button(None)
			self._mixer2.return_strip(column).set_solo_button(None)
			self._mixer2.return_strip(column).set_arm_button(None)
			self._mixer2.return_strip(column).set_crossfade_toggle(None)
			self._mixer2.return_strip(column).set_select_button(None)			#shouldn't this be somewhere else?
			self._mixer2.channel_strip(column).set_crossfade_toggle(None)
			self._mixer2.channel_strip(column).set_mute_button(None)
			self._mixer2.channel_strip(column).set_solo_button(None)
			self._mixer2.channel_strip(column).set_arm_button(None)
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(None)
				self._scene2[row].clip_slot(column).set_launch_button(None)
		for index in range(5):
			self._scene[index].set_launch_button(None)
			self._scene2[index].set_launch_button(None)
			self._scene_main[index].set_launch_button(None)
		self._session_zoom.set_nav_buttons(None, None, None, None)
		self._session_zoom2.set_nav_buttons(None, None, None, None)
		self._session_zoom_main.set_nav_buttons(None, None, None, None)
		self._session.set_track_bank_buttons(None, None)
		self._session.set_scene_bank_buttons(None, None)
		self._session2.set_track_bank_buttons(None, None)
		self._session2.set_scene_bank_buttons(None, None)
		self._session_main.set_track_bank_buttons(None, None)
		self._session_main.set_scene_bank_buttons(None, None)
		for column in range(8):
			self._mixer.channel_strip(column).set_select_button(None)
			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)
			for row in range(5):
				self._scene_main[row].clip_slot(column).set_launch_button(None)
			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].set_on_off_values(127, 0)
				self._grid[column][row].send_value(0, True)
		self._send_reset.set_buttons(tuple(None for index in range(4)))
	

	def zoom_off(self):
		for column in range(4):
			self._grid[column][5].set_on_value(MUTE[self._rgb])
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6].set_on_value(ARM[self._rgb])
			self._mixer.channel_strip(column).set_arm_button(self._grid[column][6])
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
			if(self._r_function_mode._mode_index in range(0,3)):
				self._grid[column + 4][5].set_on_value(MUTE[self._rgb])
				self._mixer2.channel_strip(column).set_mute_button(self._grid[column + 4][5])
				self._grid[column + 4][6].set_on_value(ARM[self._rgb])
				self._mixer2.channel_strip(column).set_arm_button(self._grid[column + 4][6])
				for row in range(5):
					self._scene2[row].clip_slot(column).set_launch_button(self._grid[column + 4][row])
			elif(self._r_function_mode._mode_index is 3):
				self._grid[column + 4][5].set_on_value(MUTE[self._rgb])
				self._mixer2.return_strip(column).set_mute_button(self._grid[column + 4][5])
				for row in range(5):
					self._grid[column + 4][row].send_value(USER1_COLOR[self._rgb], True)
					self._grid[column + 4][row].set_channel(RIGHT_USER1_CHANNEL)
					self._grid[column + 4][row].set_identifier(RIGHT_USER1_MAP[column][row])
					self._grid[column + 4][row].set_enabled(False)	 #this has to happen for translate to work
				#self._session_zoom2.set_ignore_buttons(True)
		if(self._r_function_mode._mode_index is 0):
			for index in range(4):
				self._grid[index + 4][7].send_value(SEND_RESET[self._rgb], True)
			self._send_reset.set_buttons(tuple(self._grid[index + 4][7] for index in range(4)))
	

	def zoom_off_m(self):
		self.deassign_dials()
		for column in range(8):
			self._grid[column][5].set_on_value(MUTE[self._rgb])
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6].set_on_value(ARM[self._rgb])
			self._mixer.channel_strip(column).set_arm_button(self._grid[column][6])
			for row in range(5):
				self._scene_main[row].clip_slot(column).set_launch_button(self._grid[column][row])
		#self._session_zoom.set_button_matrix(self._matrix)
	

	def zoom_left(self):
		track_stop_buttons = []
		track_stop_buttons2 = []
		for index in range(4):
			self._grid[index][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
			self._grid[index + 4][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons2.append(self._grid[index + 4][6])
		for index in range(5):
			self._grid[7][index].set_off_value(SCENE_LAUNCH[self._rgb])
			self._scene[index].set_launch_button(self._grid[7][index])
		self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		self._session2.set_stop_track_clip_buttons(tuple(track_stop_buttons2))
		self._session_zoom.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])	
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index + 4][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.assign_buttons(tuple(self._grid[index + 4][7] for index in range(4)), 4)
	

	def zoom_right(self):
		track_stop_buttons = []
		track_stop_buttons2 = []
		for index in range(4):
			self._grid[index][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
		for index in range(5):
			self._grid[7][index].set_off_value(SCENE_LAUNCH[self._rgb])
			self._scene2[index].set_launch_button(self._grid[7][index])
		self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		if(self._r_function_mode._mode_index < 3):
			for index in range(4):
				self._grid[index + 4][6].set_off_value(TRACK_STOP[self._rgb])
				track_stop_buttons2.append(self._grid[index + 4][6])
			self._session2.set_stop_track_clip_buttons(tuple(track_stop_buttons2))
		self._session_zoom2.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.assign_buttons(tuple(self._grid[index][7] for index in range(4)), 0)
	

	def zoom_main(self):
		track_stop_buttons = []
		for index in range(8):
			self._grid[index][6].set_on_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
		for index in range(5):
			self._grid[7][index].set_on_value(SCENE_LAUNCH[self._rgb])
			self._scene_main[index].set_launch_button(self._grid[7][index])
		self._session_main.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		self._session_zoom_main.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])	
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index + 4][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.assign_buttons(tuple(self._grid[index + 4][7] for index in range(4)), 4)
	


	"""function mode callbacks"""
	def l_function_update(self):
		mode = self._l_function_mode._mode_index
		#if(self._l_function_mode.is_enabled() is False):
		#	self._l_function_mode.set_mode_buttons(None)
		if(self._l_function_mode.is_enabled() is True):
			if(len(self._l_function_mode._modes_buttons) is 0):
				for index in range(4):
					self._mixer.channel_strip(index).set_select_button(None)
				buttons = []
				for index in range(4):
					buttons.append(self._grid[index][7]) 
				self._l_function_mode.set_mode_buttons(tuple(buttons))
			if(self._shift_mode._mode_index is 2):
				for index in range(4):
					if(mode != index):
						self._grid[index][7].turn_off()
					else:
						self._grid[index][7].turn_on()
		if(mode is 0):
			self.assign_device_dials()
			self.show_message('Mixer Split:Dials Device Mode')
		elif(mode is 1):
			self.assign_send_dials()
			self.show_message('Mixer Split:Dials Send Mode')
		elif(mode is 2):
			self.assign_split_volume_dials()
			self.show_message('Mixer Split:Dials Volume Mode')
		elif(mode is 3):
			self.assign_user_dials()
			self.show_message('Mixer Split:Dials User Map Mode')
	

	def r_function_update(self):
		mode = self._r_function_mode._mode_index
		#if(self._r_function_mode.is_enabled() is False):
		#	self._r_function_mode.set_mode_buttons(None)
			#self._session2.set_show_highlight(False)
			#self._session._highlighting_callback(self._session._track_offset, self._session._scene_offset, 4, 5, 1)
		if(self._r_function_mode.is_enabled() is True):
			if(len(self._r_function_mode._modes_buttons) is 0):
				for index in range(4):
					self._mixer2.channel_strip(index).set_select_button(None)
				buttons = []
				for index in range(4):
					buttons.append(self._grid[index + 4][7]) 
				self._r_function_mode.set_mode_buttons(tuple(buttons))
			if(self._shift_mode._mode_index is 3):
				for index in range(4):
					if(mode != index):
						self._grid[index + 4][7].turn_off()
					else:
						self._grid[index + 4][7].turn_on()
		self._session2.set_offsets(int(self._mem[mode]), self._session2._scene_offset)
		self.show_message('Mixer Split: Track Offset' + str(RIGHT_MODE_OFFSETS[mode]))
	

	def m_function_update(self):
		mode = self._m_function_mode._mode_index
		#if(self._m_function_mode.is_enabled() is False):
		#	self._m_function_mode.set_mode_buttons(None)
			#self._session.set_show_highlight(False)
			#self._session2.set_show_highlight(False)
			#self._session_main._highlighting_callback(self._session_main._track_offset, self._session_main._scene_offset, 8, 5, 1)
		if(self._m_function_mode.is_enabled() is True):
			if(len(self._m_function_mode._modes_buttons) is 0):
				for index in range(8):
					self._mixer.channel_strip(index).set_select_button(None)
				buttons = []
				for index in range(4):
					buttons.append(self._grid[index][7]) 
				self._m_function_mode.set_mode_buttons(tuple(buttons))
			if(self._shift_mode._mode_index is 4):
				for index in range(4):
					if(mode != index):
						self._grid[index][7].turn_off()
					else:
						self._grid[index][7].turn_on()
		if(mode is 0):
			self.assign_device_dials()
			self.show_message('Mixer Linked:Dials Device Mode')
		elif(mode is 1):
			self.assign_send_dials()
			self.show_message('Mixer Linked:Dials Send Mode')
		elif(mode is 2):
			self.assign_volume_dials()
			self.show_message('Mixer Linked:Dials Volume Mode')
		elif(mode is 3):
			self.assign_user_dials()
			self.show_message('Mixer Linked:Dials User Map Mode')
	

	def shift_update(self):
		self._clutch_device_selection = True
		#self.allow_updates(False)
		#if(not self._in_build_midi_map):
		#	self.set_suppress_rebuild_requests(True)
		self.deassign_channel_select_buttons()
		self.deassign_matrix()
		self.deassign_menu()
		if(self._monomod_mode._mode_index is 0):		#if monomod is not on
			if(self._shift_mode._mode_index is 0):							#if no shift is pressed
				self._shift_mode._mode_toggle1.turn_off()
				self._shift_mode._mode_toggle2.turn_off()
				if(self.split_mixer() is False):
					self.set_split_mixer(True)
				for zoom in self._zooms:
					zoom._on_zoom_value(0)
				self.zoom_off()
				self._device_selector.set_enabled(False)
				for mode in self._function_modes:
					mode.set_enabled(False)
				self.assign_channel_select_buttons()
				#self._recalculate_selected_channel()
				#self.assign_transport_to_menu()
				self.assign_session_nav_to_menu()
				self.l_function_update()
				self.r_function_update()
				self.assign_crossfader()
				self.set_highlighting_session_component(self._session)
				self._session._do_show_highlight()	
				#self._session.set_show_highlight(True)
			elif(self._shift_mode._mode_index is 1):						#if no shift is pressed, but mixer is linked
				self._shift_mode._mode_toggle1.turn_on()
				self._shift_mode._mode_toggle2.turn_on()
				if(self.split_mixer() is True):
					self.set_split_mixer(False)
				for zoom in self._zooms:
					zoom._on_zoom_value(0)
				self.zoom_off_m()
				self._device_selector.set_enabled(False)
				for mode in self._function_modes:
					mode.set_enabled(False)
				self.assign_main_channel_select_buttons()
				self.assign_session_main_nav_to_menu()
				self.m_function_update()
				self.assign_crossfader()
				self.set_highlighting_session_component(self._session_main)
				self._session_main._do_show_highlight()
			elif(self._shift_mode._mode_index > 1):						#if a shift is pressed
				self.assign_device_nav_to_menu()
				self.deassign_channel_select_buttons()
				if(self._shift_mode._mode_index is 2):					#if shift left
					self._shift_mode._mode_toggle1.turn_on()
					self.zoom_left()
					self._session_zoom._on_zoom_value(1)
					self._session.set_enabled(True) #this is a workaround so that the stop buttons still function
					self._l_function_mode.set_enabled(True)
					self.set_highlighting_session_component(self._session)
					self._session._do_show_highlight()
				elif(self._shift_mode._mode_index is 3):				#if shift right
					self._shift_mode._mode_toggle2.turn_on()
					self.zoom_right()
					self._session_zoom2._on_zoom_value(1)
					self._session2.set_enabled(True)  #this is a workaround so that the stop buttons still function
					self._r_function_mode.set_enabled(True)
					self.assign_master_fader()
					if(self._r_function_mode._mode_index < 4):
						self.set_highlighting_session_component(self._session2)
						self._session2._do_show_highlight()
				elif(self._shift_mode._mode_index is 4):				#if either shift pressed while mixer is linked
					self._shift_mode._mode_toggle1.turn_on()
					self._shift_mode._mode_toggle2.turn_on()
					self.zoom_main()
					self._session_zoom_main._on_zoom_value(1)
					self._session_main.set_enabled(True) #this is a workaround so that the stop buttons still function
					self._m_function_mode.set_enabled(True)
					self.assign_master_fader()
					self.set_highlighting_session_component(self._session_main)
					self._session_main._do_show_highlight()
				self._device_selector.set_enabled(True)
		self.allow_updates(True)
		#self.set_suppress_rebuild_requests(False)
		self._clutch_device_selection = False
		if(self._shift_mode._mode_index < 2):
			self._monobridge._send('touch', 'off')
		else:
			self._monobridge._send('touch', 'on')
	

	def monomod_mode_update(self):
		if (self._monomod_mode._mode_index == 0) or (self._host._active_client == None):
			self._host.set_enabled(False)
			self._host._set_button_matrix(None)
			self._host._set_nav_buttons(None)
			self._host._set_lock_button(None)
			self._host._set_alt_button(None)
			self._host._set_shift_button(None)
			self._livid.turn_off()
			self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r)
			self._shift_mode.update()
			#self._session._reassign_scenes()
			
		elif(self._monomod_mode._mode_index == 1):
			self._livid.turn_on()
			self.deassign_matrix()
			self.deassign_menu()
			self._monomod.reset()
			self._host._set_button_matrix(self._monomod)
			self._host._set_nav_buttons(self._menu[0:4])
			self._host._set_lock_button(self._shift_l)
			self._host._set_alt_button(self._shift_r)
			self._host._set_shift_button(self._livid)
			self._shift_mode.set_mode_toggle(None, None)
			self._host.set_enabled(True)
			self._shift_mode.update()
			#self.show_message('Monomod grid enabled')
	

	"""left control management methods"""
	def deassign_dials(self):
		for index in range(8):
			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._mixer.selected_strip().set_send_controls(None)
		self._mixer.selected_strip().set_volume_control(None)
		for track in range(4):
			self._mixer.channel_strip(track).set_volume_control(None)
			self._mixer.channel_strip(track+4).set_volume_control(None)
			self._mixer2.channel_strip(track).set_volume_control(None)
			self._mixer2.return_strip(track).set_volume_control(None)
	

	def assign_device_dials(self):
		self._ohm_type = OHM_TYPE[0]
		self._ohm = OHM_VALUE[0]
		self.deassign_dials()
		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._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_send_dials(self):
		self._ohm_type = OHM_TYPE[1]
		self._ohm = OHM_VALUE[1]
		self.deassign_dials()
		dials = []
		for index in range(4):
			dials.append(self._dial[index])
		for index in range(4):
			if(self._mixer2.return_strip(index)):
				self._mixer2.return_strip(index).set_volume_control(self._dial[index + 4])
		self._mixer.selected_strip().set_send_controls(tuple(dials))
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_volume_dials(self):
		self._ohm_type = OHM_TYPE[2]
		self._ohm = OHM_VALUE[2]
		self.deassign_dials()
		for track in range(8):
			self._mixer.channel_strip(track).set_volume_control(self._dial[track])
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_split_volume_dials(self):
		self._ohm_type = OHM_TYPE[2]
		self._ohm = OHM_VALUE[2]
		self.deassign_dials()
		for track in range(4):
			self._mixer.channel_strip(track).set_volume_control(self._dial[track])
			self._mixer2.channel_strip(track).set_volume_control(self._dial[track+4])
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_user_dials(self):
		self._ohm_type = OHM_TYPE[3]
		self._ohm = OHM_VALUE[3]
		self.deassign_dials()
		for index in range(8):
			self._dial[index].set_channel(L_USER_DIAL_CHAN)
			self._dial[index].set_identifier(L_USER_DIAL_MAP[index])
			self._dial[index].set_enabled(False)
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	


	"""menu button management methods"""
	def deassign_menu(self):
		self._device.set_lock_button(None)
		self._device.set_on_off_button(None)
		self._device_navigator.set_device_nav_buttons(None, None)	
		self._device.set_bank_nav_buttons(None, None)
		self._transport.set_play_button(None)	
		self._transport.set_record_button(None) 
		self._transport.set_stop_button(None)
		self._transport.set_loop_button(None)	
		self._transport.set_overdub_button(None)	
		self._session.set_stop_all_clips_button(None)
		self._transport.set_play_button(None)	
		self._transport.set_stop_button(None)
		self._session_main.set_track_bank_buttons(None, None)
		self._session_main.set_scene_bank_buttons(None, None)
	

	def assign_device_nav_to_menu(self):
		self._device_navigator.set_device_nav_buttons(self._menu[2], self._menu[3]) 
		self._device.set_bank_nav_buttons(self._menu[0], self._menu[1])
	

	def assign_transport_to_menu(self):
		self._transport.set_play_button(self._menu[0])	
		self._transport.set_record_button(self._menu[2])
		self._transport.set_stop_button(self._menu[1])
		session.set_stop_all_clips_button(self._menu[3])
	

	def assign_session_nav_to_menu(self):
		self._session.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_monomod_shift_to_menu(self):
		self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[2]) 
		self._device.set_bank_nav_buttons(self._menu[1], self._menu[0])
	

	def assign_session_bank_to_menu(self):
		self._session.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_session2_bank_to_menu(self):
		self._session2.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session2.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_session_main_nav_to_menu(self):
		self._session_main.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session_main.set_scene_bank_buttons(self._menu[1], self._menu[0])
	


	"""channel selection management methods"""
	def deassign_channel_select_buttons(self):
		for index in range(8):
			if(self._mixer.channel_strip(index)):
				self._mixer.channel_strip(index).set_select_button(None)
			self._grid[index][7].release_parameter()
		for index in range(4):
			self._mixer2.channel_strip(index).set_select_button(None)
			self._mixer2.return_strip(index).set_select_button(None)
			self._mixer2.master_strip().set_select_button(None)
			self._grid[index + 4][7].release_parameter()
	

	def assign_channel_select_buttons(self):
		for index in range(4):
			#if(self._mixer.channel_strip(index)):
			self._grid[index][7].set_on_off_values(127, 0)
			self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
		if(self._r_function_mode._mode_index < 3):
			for index in range(4):
				self._grid[index][7].set_on_off_values(127, 0)
				self._mixer2.channel_strip(index).set_select_button(self._grid[index + 4][7])	
		else:
			for index in range(4):
				self._grid[index][7].set_on_off_values(1, 0)
				self._mixer2.return_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_return_select_buttons(self):
		for index in range(4):
			self._grid[index + 4][7].set_off_value(0) 
			if(self._mixer.channel_strip(index)):
				self._grid[index + 4][7].set_on_value(1)
				self._mixer.channel_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_l_channel_select_buttons(self):
		self._mixer.set_select_buttons(None, None)
		self._session.set_select_buttons(None, None)
		for index in range(4):
			self._grid[index][7].set_off_value(0)
			if(self._mixer.channel_strip(index)):
				self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
	

	def assign_r_channel_select_buttons(self):
		self._mixer2.set_select_buttons(None, None)
		self._session2.set_select_buttons(None, None)
		for index in range(4):
			self._grid[index + 4][7].set_off_value(0)
			if(self._mixer2.channel_strip(index)):
				self._mixer2.channel_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_main_channel_select_buttons(self):
		for index in range(8):
			self._grid[index][7].set_off_value(0)
			if(self._mixer.channel_strip(index)):
				self._grid[index][7].set_on_value(127)
				self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
	

	def assign_master_fader(self):
		self._mixer.set_crossfader_control(None)
		self._mixer.master_strip().set_volume_control(self._fader[1])
	

	def assign_crossfader(self):
		self._mixer.master_strip().set_volume_control(None)
		self._mixer.set_crossfader_control(self._fader[1])
	


	"""called on timer"""
	def update_display(self):
		super(BlockMod, self).update_display()
		if(self._timer == 0):
			self._shift_pressed_timer = -12
	

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

	def handle_sysex(self, midi_bytes):
		pass
	

	def _on_session_offset_changes(self):
		if self._r_function_mode._mode_index in range(0,4):
			self._mem[int(self._r_function_mode._mode_index)] = self._session2.track_offset()
	



#	a
Example #9
0
class OhmModes(ControlSurface):
	__module__ = __name__
	__doc__ = ' OhmModes controller script '


	def __init__(self, c_instance):
		super(OhmModes, self).__init__(c_instance)
		self._version_check = 'b996'
		self._host_name = 'Ohm'
		self._color_type = 'OhmRGB'
		self._rgb = 0
		self._timer = 0
		self._touched = 0
		self.flash_status = 1
		self._backlight = 127
		self._backlight_type = 'static'
		self._ohm = 127
		self._ohm_type = 'static'
		self._pad_translations = PAD_TRANSLATION
		self._device_selection_follows_track_selection = FOLLOW
		self._keys_octave = 5
		self._keys_scale = 0
		self._tempo_buttons = None
		with self.component_guard():
			self._setup_monobridge()
			self._setup_controls()
			self._setup_m4l_interface()
			self._setup_transport_control()
			self._setup_mixer_control()
			self._setup_session_control()
			self._setup_device_control()
			self._setup_crossfader()
			self._setup_translations()
			self._setup_mod()
			self._setup_modes()
			self._assign_page_constants()
			self._last_device = None
			self.song().view.add_selected_track_listener(self._update_selected_device)
			self.show_message('OhmModes Control Surface Loaded')
			self._send_midi(tuple(switchxfader))
		if FORCE_TYPE is True:
			self._rgb = FORCE_COLOR_TYPE
		else:
			self.schedule_message(10, self.query_ohm, None)
		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< OhmModes ' + str(self._version_check) + ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
		debug('DEBUG ON for OhmModes script.')
	

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

	def update_display(self):
		super(OhmModes, self).update_display()
		self._timer = (self._timer + 1) % 256
		self.flash()
		self.strobe()
	

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

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

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

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

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

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

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

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

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

			self._matrix.add_row(tuple(button_row))

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

			self._monomod.add_row(tuple(button_row))

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

			self._dial_matrix.add_row(tuple(dial_row))

		self._menu_matrix = ButtonMatrixElement([self._menu])
	

	def _setup_m4l_interface(self):
		self._m4l_interface = M4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard)
		self.get_control_names = self._m4l_interface.get_control_names
		self.get_control = self._m4l_interface.get_control
		self.grab_control = self._m4l_interface.grab_control
		self.release_control = self._m4l_interface.release_control
	

	def _setup_translations(self):
		controls = []
		for array in self._grid:
			for button in array:
				controls.append(button)
		if FADER_BANKING:
			controls = controls + self._dial
		if DIAL_BANKING:
			controls = controls + self._dial
		self._translations = TranslationComponent(controls, USER_CHANNEL)
		self._translations.layer = Layer(priority = 7, channel_selector_buttons = self._menu_matrix)
	

	def _setup_mod(self):
		self.monomodular = get_monomodular(self)
		self.monomodular.name = 'monomodular_switcher'
		self.modhandler = OhmModHandler(self)
		self.modhandler.name = 'ModHandler' 
		self.modhandler.layer = Layer(priority = 5, 
									grid = self._monomod,
									nav_up_button = self._menu[2],
									nav_down_button = self._menu[5],
									nav_left_button = self._menu[3],
									nav_right_button =  self._menu[4],
									shift_button = self._menu[1],
									alt_button = self._menu[0],
									parameter_controls = self._dial_matrix)
		self.modhandler.legacy_shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6,
									channel_buttons = self._monomod.submatrix[:, 1:2],
									nav_matrix = self._monomod.submatrix[4:8, 2:6]))
		self.modhandler.shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6, 
									device_selector_matrix = self._monomod.submatrix[:, :1],
									lock_button = self._livid,
									key_buttons = self._monomod.submatrix[:, 7:8]))
									
		self.modhandler.set_enabled(False)
		self.modhandler.set_mod_button(self._livid)
	

	def _setup_modes(self):
		self._shift_mode = ShiftModeComponent(self)
		self._shift_mode.name = 'Shift_Mode'
		#self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r, self._livid)
		self._shift_mode.layer = Layer(priority = 4, mode_toggle1 = self._shift_l, mode_toggle2 = self._shift_r, mode_toggle3 = self._livid)
		self._shift_mode.set_enabled(True)
		self._scale_mode = ScaleModeComponent(self)
		self._scale_mode.name = 'Scale_Mode'
		self._octave_mode = OctaveModeComponent(self)
		self._octave_mode.name = 'Octave_Mode'
	

	def _setup_transport_control(self):
		self._transport = TransportComponent()
		self._transport.name = 'Transport'
		#self._transport.layer = Layer(priority = 4, play_button = self._menu[2], stop_button = self._menu[3])
	

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

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

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

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

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

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

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

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

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

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

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

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

	def _get_num_tracks(self):
		return self.num_tracks
	

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

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

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

			for column in range(7):
				self._mixer.channel_strip(column).set_crossfade_toggle(None)
				self._mixer.channel_strip(column).set_mute_button(None)
				self._mixer.channel_strip(column).set_solo_button(None)
				self._mixer.channel_strip(column).set_arm_button(None)
				self._mixer.channel_strip(column).set_send_controls(None)
				self._mixer.channel_strip(column).set_pan_control(None)
				self._mixer.track_eq(column).set_enabled(False)
				for row in range(5):
					self._scene[row].clip_slot(column).set_launch_button(None)
			for column in range(8):
				self._button[column]._on_value = SELECT_COLOR[self._rgb]
				for row in range(8):
					#self._grid[column][row].set_channel(0)
					self._grid[column][row].release_parameter()
					self._grid[column][row].use_default_message()
					self._grid[column][row].set_enabled(True)
					self._grid[column][row].send_value(0, True)
					self._grid[column][row]._on_value = 127
					self._grid[column][row]._off_value = 0
					self._grid[column][row].force_next_send()
			for index in range(6):
				self._menu[index]._on_value = 127
				self._menu[index]._off_value = 0
			for index in range(16):
				self._dial[index].use_default_message()
				self._dial[index].release_parameter()
			self._device.set_parameter_controls(None)
			self._device.set_enabled(False)
			self._device_navigator.set_enabled(False)
			self._mixer.update()
			self._matrix.reset()
		self.request_rebuild_midi_map()
	

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	def assign_mod(self):
		self.modhandler.set_enabled(True)
	

	def assign_translation(self):
		self._translations.set_enabled(True)
	

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

		self.request_rebuild_midi_map()
	

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

	def handle_sysex(self, midi_bytes):
		#self.log_message('sysex: ' + str(midi_bytes))
		if len(midi_bytes) > 10:
			if midi_bytes[:11] == tuple([240,
			 126,
			 0,
			 6,
			 2,
			 0,
			 1,
			 97,
			 1,
			 0,
			 7]):
				self.log_message(str('>>>color detected'))
				self._rgb = 0
				for button in self._button:
					button._color_map = COLOR_MAP
				for column in self._grid:
					for button in column:
						button._color_map = COLOR_MAP
			elif midi_bytes[:11] == tuple([240,
			 126,
			 0,
			 6,
			 2,
			 0,
			 1,
			 97,
			 1,
			 0,
			 2]):
				self.log_message(str('>>>mono detected'))
				self._rgb = 1
				for button in self._button:
					button._color_map = [127 for index in range(0, 7)]
				for column in self._grid:
					for button in column:
						button._color_map = [127 for index in range(0, 7)]
		self._assign_session_colors()
	

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

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

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

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

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

		ret += ' '
		return ret
	

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

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

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

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

		return clip_names
Example #10
0
class AumPC20(APC):
    """ Monomodular script for Akai's APC20 Controller """
    def __init__(self, c_instance, *a, **k):
        self._shift_modes = None
        super(AumPC20, self).__init__(c_instance, *a, **k)

    def disconnect(self):
        self._shift_modes = None
        super(AumPC20, self).disconnect()

    def _activate_combination_mode(self, track_offset, support_devices):
        super(AumPC20,
              self)._activate_combination_mode(track_offset, support_devices)
        if support_devices:
            self._shift_modes.invert_assignment()

    def _setup_session_control(self):
        is_momentary = True
        self._shift_button = AumPCMonoButtonElement(is_momentary,
                                                    MIDI_NOTE_TYPE, 0, 81,
                                                    'Shift_Button', self)
        self._session = APCSessionComponent(8, 5)
        self._session.name = 'Session_Control'
        self._matrix = ButtonMatrixElement()
        self._matrix.name = 'Button_Matrix'
        scene_launch_buttons = [
            AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                   (index + 82),
                                   'Scene_' + str(index) + '_Launch_Button',
                                   self) for index in range(5)
        ]
        self._scene_launch_buttons = scene_launch_buttons
        track_stop_buttons = [
            AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52,
                                   'Track_' + str(index) + '_Stop_Button',
                                   self) for index in range(8)
        ]
        self._track_stop_buttons = track_stop_buttons
        for index in range(len(scene_launch_buttons)):
            scene_launch_buttons[index].name = 'Scene_' + str(
                index) + '_Launch_Button'

        for index in range(len(track_stop_buttons)):
            track_stop_buttons[index].name = 'Track_' + str(
                index) + '_Stop_Button'

        self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
        self._session.set_stop_track_clip_value(2)
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                button = AumPCMonoButtonElement(
                    is_momentary, MIDI_NOTE_TYPE, track_index,
                    (scene_index + 53),
                    '_Clip_' + str(scene_index) + '_Button', self)
                button.name = str(track_index) + '_Clip_' + str(
                    scene_index) + '_Button'
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                clip_slot.set_triggered_to_play_value(2)
                clip_slot.set_triggered_to_record_value(4)
                clip_slot.set_stopped_value(5)
                clip_slot.set_started_value(1)
                clip_slot.set_recording_value(3)
                clip_slot.set_launch_button(button)

            self._matrix.add_row(tuple(button_row))

        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        self._session_zoom = ShiftableZoomingComponent(
            self._session, tuple(track_stop_buttons))
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_button_matrix(self._matrix)
        self._session_zoom.set_zoom_button(self._shift_button)
        self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
        self._session_zoom.set_stopped_value(3)
        self._session_zoom.set_selected_value(5)

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._solo_buttons = []
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            solo_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                                 track, 49,
                                                 str(track) + '_Solo_Button',
                                                 self)
            self._solo_buttons.append(solo_button)
            mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track,
                                        50)
            solo_button.name = str(track) + '_Solo_Button'
            mute_button.name = str(track) + '_Mute_Button'
            strip.set_solo_button(solo_button)
            strip.set_mute_button(mute_button)
            strip.set_shift_button(self._shift_button)
            strip.set_invert_mute_feedback(True)

        master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
        prehear_control = EncoderElement(
            MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
        master_volume_control.name = 'Master_Volume_Control'
        prehear_control.name = 'Prehear_Volume_Control'
        self._mixer.set_prehear_volume_control(prehear_control)
        self._mixer.master_strip().set_volume_control(master_volume_control)

    def _setup_custom_components(self):
        is_momentary = True
        master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                             80)
        master_select_button.name = 'Master_Select_Button'
        self._master_select_button = master_select_button
        select_buttons = []
        arm_buttons = []
        sliders = []
        for track in range(8):
            select_buttons.append(
                AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51,
                                       str(track) + '_Select_Button', self))
            arm_buttons.append(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48))
            sliders.append(
                MonoEncoderElement(MIDI_CC_TYPE, track, 7,
                                   Live.MidiMap.MapMode.absolute,
                                   'Slider_' + str(track), track, self))
            select_buttons[-1].name = str(track) + '_Select_Button'
            arm_buttons[-1].name = str(track) + '_Arm_Button'
            #sliders[-1].name = str(track) + '_Volume_Control'
        self._select_buttons = select_buttons

        transport = TransportComponent()
        transport.name = 'Transport'
        slider_modes = SliderModesComponent(self._mixer, tuple(sliders))
        slider_modes.name = 'Slider_Modes'
        self._shift_modes = AumPC20ShiftableSelectorComponent(
            tuple(select_buttons), master_select_button, tuple(arm_buttons),
            self._matrix, self._session, self._session_zoom, self._mixer,
            transport, slider_modes, self._send_introduction_message, self)
        self._shift_modes.name = 'Shift_Modes'
        self._shift_modes.set_mode_toggle(self._shift_button)
        self._device = DeviceComponent()

    def _product_model_id_byte(self):
        return 123

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

    def _setup_monomod(self):
        self._host = AumPC20MonomodComponent(self)
        self._host.name = 'Monomod_Host'
        self._host._navbox_selected = 16
        self._host._navbox_unselected = 1
        self.hosts = [self._host]
        self._monomod = ButtonMatrixElement()
        self._monomod.name = 'Monomod'
        for row in range(5):
            button_row = []
            for column in range(8):
                button_row.append(self._matrix.get_button(column, row))
            self._monomod.add_row(tuple(button_row))
        self._monomod.add_row(tuple(self._track_stop_buttons))
        self._monomod.add_row(tuple(self._select_buttons))
        self._monomod.add_row(tuple(self._solo_buttons))
        self._monomod_mode = MonomodModeComponent(self._monomod_mode_update,
                                                  self)
        self._monomod_mode.name = "Monomod_Mode_Component"
        #self._shift_button.add_value_listener(self._shift_value)

    def _shift_value(self, value):
        if value > 0:
            self._mixer.master_strip().set_select_button(None)
            self._monomod_mode.set_mode_toggle(self._master_select_button)
        else:
            self._mixer.master_strip().set_select_button(
                self._master_select_button)
            self._monomod_mode.set_mode_toggle(None)

    def _monomod_mode_update(self):
        self.log_message('mode update: ' + str(self._monomod_mode._mode_index))
        if (self._monomod_mode._mode_index == 0) or (self._host._active_client
                                                     == None):
            self.flash_status = 0
            self._host.set_enabled(False)
            self._host._set_button_matrix(None)
            #self._host._set_nav_buttons(None)
            self._host._set_lock_button(None)
            self._host._set_alt_button(None)
            self._host._set_shift_button(None)
            self._host._set_nav_buttons(None)
            self._scene_launch_buttons[2].set_on_off_values(127, 0)
            self._scene_launch_buttons[3].set_on_off_values(127, 0)
            self._monomod.reset()
            self._shift_modes.set_enabled(True)
            #self._session.set_track_bank_buttons(self._right_button, self._left_button)
            #self._session.set_scene_bank_buttons(self._down_button, self._up_button)
            for track in range(8):
                self._mixer.channel_strip(track).set_select_button(
                    self._select_buttons[track])
                self._mixer.channel_strip(track).set_solo_button(
                    self._solo_buttons[track])
            #self._transport.set_nudge_buttons(self._nudge_up_button, self._nudge_down_button)
            self._session.set_enabled(True)
            self._session_zoom._is_zoomed_out = False
            self._session_zoom.set_enabled(True)
            self.request_rebuild_midi_map()
            self._master_select_button.turn_off()

        elif (self._monomod_mode._mode_index == 1):
            if self._shift_modes._note_mode_active is True:
                self._shift_modes._mode_callback(ABLETON_MODE)
                self._shift_modes._note_mode_active = False
                self._session_zoom.set_ignore_buttons(False)
                self._shift_modes._transport.update()
                self._shift_modes._on_note_mode_changed()
            #self._transport.set_nudge_buttons(None, None)
            self._shift_modes.set_enabled(False)
            for track in range(8):
                self._mixer.channel_strip(track).set_select_button(None)
                self._mixer.channel_strip(track).set_solo_button(None)
            for scene in range(5):
                self._scene_launch_buttons[scene].turn_off()
            self._session.set_enabled(False)
            self._session_zoom.set_enabled(False)
            #self._session.set_track_bank_buttons(None, None)
            #self._session.set_scene_bank_buttons(None, None)
            self.flash_status = 1
            self._monomod.reset()
            self._host._set_button_matrix(self._monomod)
            #self._host._set_nav_buttons([self._up_button, self._down_button, self._left_button, self._right_button])
            self._host._set_shift_button(self._shift_button)
            self._host._set_lock_button(self._scene_launch_buttons[0])
            self._host._set_alt_button(self._scene_launch_buttons[1])
            self._host._set_nav_buttons(
                [self._scene_launch_buttons[2], self._scene_launch_buttons[3]])
            self._host.set_enabled(True)
            self.request_rebuild_midi_map()
            self._master_select_button.turn_on()
            #self.log_message('mod mode')

    """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, MonoEncoderElement):
            self._monobridge._send(sender.name, 'lcd_name',
                                   str(self.generate_strip_string(name)))
            self._monobridge._send(sender.name, 'lcd_value',
                                   str(self.generate_strip_string(value)))

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

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

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

    def update_display(self):
        super(AumPC20, self).update_display()
        self._timer = (self._timer + 1) % 256
        self.flash()

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

    def set_appointed_device(self, *a, **k):
        pass
Example #11
0
class Crate(ControlSurface):
	__module__ = __name__
	__doc__ = " Monomodular controller script for Crate "


	def __init__(self, *a, **k):
		super(Crate, self).__init__(*a, **k)
		self._host_name = 'Crate'
		self._version_check = '1.0'
		self._rgb = 0
		self._timer = 0
		self._touched = 0
		self.flash_status = 1
		with self.component_guard():
			self._setup_monobridge()
			self._setup_controls()
			self._setup_session()
			self._setup_next_buttons()
			self._setup_tempo()
			self._setup_modes()
			self._create_fallback_control_owner()
		self.schedule_message(1, self._open_log)
		self.schedule_message(3, self._initialize_surface)
	

	def _open_log(self):
		self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) + " " + str(self._version_check) + " log opened =>>>>>>>>>>>>>>>>>>>") 
		self.show_message(str(self._host_name) + ' Control Surface Loaded')
	

	def _initialize_surface(self):
		debug('setting to main mode')
		#self._main_modes.selected_mod = 'Main'
		#self._session.set_enabled(True)
	

	def port_settings_changed(self):
		debug('port settings changed!')
		self._connected = False
		super(Crate, self).port_settings_changed()
	

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

	def _with_shift(self, button):
		return ComboElement(button, modifiers=[self._shift_button])
	

	def _setup_controls(self):
		self._button = [CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index, name = 'Button_' + str(index), script = self) for index in range(20)]
		self._track_button = [CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index+50, name = 'Button_' + str(index+50), script = self) for index in range(6)]
		self._next_button = [CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index+60, name = 'Button_' + str(index+60), script = self) for index in range(2)]
		self._crate_button = [CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index+70, name = 'Button_' + str(index+70), script = self) for index in range(3)]
		#self._tempo_slider = EncoderElement(MIDI_CC_TYPE, 0, 0, Live.MidiMap.MapMode.absolute, name = 'Slider')

		self._matrix = ButtonMatrixElement(name = 'Matrix', rows = [[self._button[index]] for index in range(20)])

		self._left_matrix = ButtonMatrixElement(name = 'Left_Matrix', rows = [[self._button[index]] for index in range(10)])
		self._right_matrix = ButtonMatrixElement(name = 'Right_Matrix', rows = [[self._button[index+10]] for index in range(10)])

		self._track_select_matrix = ButtonMatrixElement(name = 'Track_Matrix', rows = [self._track_button])

	

	def _setup_session(self):
		self._left_session = CrateSessionComponent(script = self, name = 'Session_Component_A', num_tracks = 1, num_scenes = 20, autonaming = True, is_enabled = False, layer = Layer(priority = 1, clip_launch_buttons = self._matrix, track_nav_buttons = self._track_select_matrix))
		self._left_session.set_group_track('DECK A')
		self._left_session_zooming = SessionZoomingComponent(session = self._left_session)

		self._right_session = CrateSessionComponent(script = self, name = 'Session_Component_B', num_tracks = 1, num_scenes = 20, autonaming = True, is_enabled = False, layer = Layer(priority = 1, clip_launch_buttons = self._matrix, track_nav_buttons = self._track_select_matrix))
		self._right_session.set_group_track('DECK B')
		self._right_session_zooming = SessionZoomingComponent(session = self._right_session)

		self._left_set_session = CrateSetSessionComponent(script = self, name = 'Session_Component_SETA', num_tracks = 1, num_scenes = 10, autonaming = True, is_enabled = False, layer = Layer(priority = 1, clip_launch_buttons = self._left_matrix))
		self._left_set_session.set_group_track('SET A')
		self._left_set_session_zooming = SessionZoomingComponent(session = self._left_set_session)

		self._right_set_session = CrateSetSessionComponent(script = self, name = 'Session_Component_SETB', num_tracks = 1, num_scenes = 10, autonaming = True, is_enabled = False, layer = Layer(priority = 1, clip_launch_buttons = self._right_matrix))
		self._right_set_session.set_group_track('SET B')
		self._right_set_session_zooming = SessionZoomingComponent(session = self._right_set_session)
	

	def _setup_next_buttons(self):
		self._next_a_button = FireNextClipComponent()
		self._next_a_button.set_track('SET A')
		self._next_a_button.layer = Layer(button = self._next_button[0])

		self._next_b_button = FireNextClipComponent()
		self._next_b_button.set_track('SET B')
		self._next_b_button.layer = Layer(button = self._next_button[1])
	

	def _setup_tempo(self):
		self._on_tempo_changed.subject = self.song()
		self._on_tempo_changed()
	

	@subject_slot('value')
	def _on_tempo_slider_value(self, value):
		self.song().tempo = ((value/127.)*979.)+20.
	

	@subject_slot('tempo')
	def _on_tempo_changed(self, *a, **k):
		debug('on tempo changed:', self.song().tempo)
		new_tempo = self.song().tempo
		#self._on_tempo_slider_value.subject and self._on_tempo_slider_value.subject.send_value(((new_tempo-20)/979)*127)
		self.send_tempo('Tempo '+str(new_tempo))
	

	def _setup_modes(self):

		next_buttons = CompoundMode(self._next_a_button, self._next_a_button)
		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('disabled', None)
		self._main_modes.add_mode('left_session', [self._left_session, next_buttons])
		self._main_modes.add_mode('right_session', [self._right_session, next_buttons])
		self._main_modes.add_mode('set_session', [self._left_set_session, self._right_set_session, next_buttons])
		self._main_modes.layer = Layer(priority = 6, left_session_button = self._crate_button[0], right_session_button = self._crate_button[1], set_session_button = self._crate_button[2])
		self._main_modes.selected_mode = 'set_session'
		self._main_modes.set_enabled(True)

		#self._next_a_button.set_enabled(True)
		#self._next_b_button.set_enabled(True)
	

	def _create_fallback_control_owner(self):
		self.register_disconnectable(SimpleLayerOwner(layer=Layer(_matrix=self._matrix, priority=0)))
	

	def update_display(self):
		super(Crate, self).update_display()
		self._timer = (self._timer + 1) % 256
		self.flash()
	

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

	@subject_slot('appointed_device')
	def _on_device_changed(self):
		debug('appointed device changed, script')
	

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

		ret += ' '
		ret = ret.replace(' ', '_')
		assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
		return ret
	

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

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

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

	def handle_sysex(self, midi_bytes):
		pass
	

	def disconnect(self):
		self.log_message("<<<<<<<<<<<<<<<<<<<<<<<<< " + str(self._host_name) + " log closed >>>>>>>>>>>>>>>>>>>>>>>>>")
		super(Crate, self).disconnect()
	

	def handle_sysex(self, midi_bytes):
		#debug('sysex: ', str(midi_bytes))
		pass
	

	def clip_name(self, sender, name):
		offset = self._button.index(sender)
		shortname = encode_name_to_sysex(name)
		display_sysex = (240,
			 0,
			 0,
			 102,
			 1,
			 offset) + tuple(shortname) + (247,)
		self._do_send_midi(display_sysex)
	

	def track_name(self, offset, name):
		shortname = encode_name_to_sysex(name)
		display_sysex = (240,
			 0,
			 0,
			 102,
			 2,
			 offset) + tuple(shortname) + (247,)
		self._do_send_midi(display_sysex)
	

	def send_tempo(self, tempo):
		shortname = encode_name_to_sysex(tempo)
		display_sysex = (240,
			 0,
			 0,
			 102,
			 3,) + tuple(shortname) + (247,)
		self._do_send_midi(display_sysex)
	



#	a
class GuitarWing(ControlSurface):
	__module__ = __name__
	__doc__ = " GuitarWing controller script "


	def __init__(self, c_instance):
		super(GuitarWing, self).__init__(c_instance)
		self._connected = False
		self._host_name = 'GuitarWing'
		self._color_type = 'OhmRGB'
		self.oscServer = None
		self.log_message("<<<<<<<<<<<<<<<<<= GuitarWing log opened =>>>>>>>>>>>>>>>>>>>>>") 
		self._timer = 0
		self._current_nav_buttons = []
		self.flash_status = 1
		self._clutch_device_selection = False
		self._touched = 0
		self._last_selected_track = None
		self._last_selected_track_arm = False
		self._device_selection_follows_track_selection = True
		with self.component_guard():
			self._setup_monobridge()
			self._setup_controls()
			self._setup_m4l_interface()
			#self._setup_OSC_layer()
			self._setup_device_control()
			self._setup_transport_control()
			#self._setup_selected_session_control()
			self._setup_mixer_control()
			self._setup_session_control()
			#self._setup_step_sequencer()
			#self._device.add_device_listener(self._on_new_device_set)
			self._device.set_parameter_controls(tuple([self._fader[0], self._fader[1], self._fader[2], self._accel[2], self._ccs[0], self._ccs[1], self._ccs[2], self._ccs[3]]))  #, self._fader_button[0], self._fader_button[1], self._fader_button[2], self._padCC[4]]))
			self._mixer.set_select_buttons(self._button[1], self._button[0])
			#self._session.set_scene_launch_buttons(self._pad[:4])
			for index in range(4):
				self._scene[index].set_launch_button(self._pad[index])
			#for index in range(4):
			#	self._pad[index].set_identifier(36+index)
			#	self._pad[index].set_channel(CHANNEL)
			#	self._pad[index].set_enabled(False)
			self._transport.set_stop_button(self._button[6])
			self._transport.set_loop_button(self._button[7])
			self._transport.set_seek_backward_button(self._button[8])
			self._transport.set_record_button(self._button[9])
			#self._on_select_track_down_value.subject = self._button[0]
			#self._on_select_track_up_value.subject = self._button[1]

	

	@subject_slot('value')
	def _on_select_track_up_value(self, value):
		if value:
			pass
	

	@subject_slot('value')
	def _on_select_track_down_value(self, value):
		if value:
			pass
	

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

	def _setup_controls(self):
		is_momentary = True
		self._button = [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, BUTTONS[index], 'Button_' + str(index), self) for index in range(10)]

		self._fader = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, SLIDERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self) for index in range(3)]
		#self._fader_button = [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, index, 'Fader_Button_' + str(index), self) for index in range(3)]
		self._fader_button = [MonoEncoderElement(MIDI_NOTE_TYPE, CHANNEL, SLIDERS[index], Live.MidiMap.MapMode.absolute, 'Fader_Button_' + str(index), index, self) for index in range(3)]

		self._ccs = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CCS[index], Live.MidiMap.MapMode.absolute, 'CCs_' + str(index), index, self) for index in range(4)]

		self._pad =  [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, PADS[index], 'Pad_' + str(index), self) for index in range(5)]
		self._padCC = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, PADS[index], Live.MidiMap.MapMode.absolute, 'PadCC_' + str(index), index, self) for index in range(5)]

		self._accel = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, ACCELS[index], Live.MidiMap.MapMode.absolute, 'Accel_' + str(index), index, self) for index in range(3)]
	

	def _setup_mixer_control(self):
		is_momentary = True
		self._num_tracks = (1) #A mixer is one-dimensional; 
		self._mixer = MixerComponent(1, 0, False, False)
		self._mixer.name = 'Mixer'
		self._mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		for index in range(1):
			self._mixer.channel_strip(index)._invert_mute_feedback = True
			self._mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
		#for index in range(4):
		#	self._mixer.return_strip(index).name = 'Mixer_ReturnStrip_' + str(index)
		self._mixer.selected_strip().name = 'Mixer_SelectedStrip'
		self.song().view.selected_track = self._mixer.channel_strip(0)._track 
	

	def _setup_session_control(self):
		self._session = GuitarWingSessionComponent(1, 4, self)
		self._session.name = "Session"
		self._session.set_offsets(0, 0)	 
		self._session.set_stop_clip_value(STOP_CLIP)
		self._scene = [None for index in range(4)]
		for row in range(4):
			self._scene[row] = self._session.scene(row)
			self._scene[row].name = 'Scene_' + str(row)
			for column in range(1):
				clip_slot = self._scene[row].clip_slot(column)
				clip_slot.name = str(column) + '_Clip_Slot_' + str(row)
				clip_slot.set_triggered_to_play_value(CLIP_TRG_PLAY)
				clip_slot.set_triggered_to_record_value(CLIP_TRG_REC)
				clip_slot.set_stopped_value(CLIP_STOP)
				clip_slot.set_started_value(CLIP_STARTED)
				clip_slot.set_recording_value(CLIP_RECORDING)
		self._session.set_mixer(self._mixer)
		#self._session.set_track_banking_increment(TRACK_BANKING_INCREMENT)
		self.set_highlighting_session_component(self._session)
		self._session._do_show_highlight()
	

	def _setup_transport_control(self):
		self._transport = TransportComponent()
	

	def _setup_selected_session_control(self):
		self._selected_session = GuitarWingSessionComponent(1, 16, self)
		self._selected_session.name = "SelectedSession"
		self._selected_session.set_offsets(0, 0)	 
		self._selected_session.set_stop_clip_value(STOP_CLIP)
		self._selected_scene = [None for index in range(16)]
		for row in range(16):
			self._selected_scene[row] = self._selected_session.scene(row)
			self._selected_scene[row].name = 'SelectedScene_' + str(row)
			clip_slot = self._selected_scene[row].clip_slot(0)
			clip_slot.name = 'Selected_Clip_Slot_' + str(row)
			clip_slot.set_triggered_to_play_value(CLIP_TRG_PLAY)
			clip_slot.set_triggered_to_record_value(CLIP_TRG_REC)
			clip_slot.set_stopped_value(CLIP_STOP)
			clip_slot.set_started_value(CLIP_STARTED)
			clip_slot.set_recording_value(CLIP_RECORDING)
	

	def _setup_device_control(self):
		self._device = GuitarWingDeviceComponent(self)  #, MOD_BANK_DICT, MOD_TYPES)
		self._device.name = 'Device_Component'

		self.set_device_component(self._device)
		self._device.set_enabled(True)
	

	def _setup_m4l_interface(self):
		self._m4l_interface = M4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard)
		self.get_control_names = self._m4l_interface.get_control_names
		self.get_control = self._m4l_interface.get_control
		self.grab_control = self._m4l_interface.grab_control
		self.release_control = self._m4l_interface.release_control
	

	def _setup_mod(self):
		if isinstance(__builtins__, dict):
			if not 'monomodular' in __builtins__.keys() or not isinstance(__builtins__['monomodular'], ModRouter):
				__builtins__['monomodular'] = ModRouter()
		else:
			if not hasattr(__builtins__, 'monomodular') or not isinstance(__builtins__['monomodular'], ModRouter):
				setattr(__builtins__, 'monomodular', ModRouter())
		self.monomodular = __builtins__['monomodular']
		if not self.monomodular.has_host():
			self.monomodular.set_host(self)
		self.monomodular.name = 'monomodular_switcher'
		self.modhandler = GuitarWingModHandler(script = self)
		self.modhandler.name = 'ModHandler'
		# self.log_message('mod is: ' + str(self.monomodular) + ' ' + str(__builtins__['monomodular']))
	

	def _setup_OSC_layer(self):
		self._OSC_id = 0
		if hasattr(__builtins__, 'control_surfaces') or (isinstance(__builtins__, dict) and 'control_surfaces' in __builtins__.keys()):
			for cs in __builtins__['control_surfaces']:
				if cs is self:
					break
				elif isinstance(cs, GuitarWing):
					self._OSC_id += 1

		self._prefix = '/Live/GuitarWing/'+str(self._OSC_id)
		self._outPrt = OSC_OUTPORT
		if not self.oscServer is None:
			self.oscServer.shutdown()
		self.oscServer = RemixNet.OSCServer('localhost', self._outPrt, 'localhost', 10001)
	

	def _deassign_all(self):
		self.modhandler._fader_color_override = False
		self._send_midi(tuple([240, 0, 1, 97, 12, 50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 247]))
		self._send_midi(tuple([191, 122, 64]))		#turn local OFF for CapFaders
		#for index in range(8):
		#	self._send_midi(tuple([191, index+10, 125]))
		#self._send_midi(tuple([191, 18, 105]))
		self._current_nav_buttons = []
		with self.component_guard():

			self.release_controlled_track()

			self._step_sequencer.set_loop_selector_matrix(None)
			self._step_sequencer.set_quantization_buttons(None)
			self._step_sequencer.set_follow_button(None)
			self._step_sequencer.set_button_matrix(None)
			self._step_sequencer.set_drum_matrix(None)
			self._step_sequencer.set_drum_bank_up_button(None)
			self._step_sequencer.set_drum_bank_down_button(None)
			self._step_sequencer.set_mute_button(None)
			self._step_sequencer.set_solo_button(None)
			self._step_sequencer.set_playhead(None)

			self._on_note_matrix_pressed.subject = None
			self._note_sequencer.set_loop_selector_matrix(None)
			self._note_sequencer.set_quantization_buttons(None)
			self._note_sequencer.set_follow_button(None)
			self._note_sequencer.set_button_matrix(None)
			self._note_sequencer.set_playhead(None)

			self._drumgroup.set_drum_matrix(None)
			self.modhandler._assign_keys(None)
			self.modhandler._assign_base_grid(None)
			self.modhandler._assign_base_grid_CC(None)
			self.modhandler.set_shift_button(None)
			self.modhandler.set_device_component(None)
			self._transport.set_overdub_button(None)
			self._recorder.set_new_button(None)
			self._recorder.set_record_button(None)
			self._recorder.set_length_button(None)
			self._recorder.set_length_buttons(None)
			self._offset_component.deassign_all()
			self._vertical_offset_component.deassign_all()
			self._scale_offset_component.deassign_all()
			self._device_navigator.deassign_all()
			self._device.deassign_all()
			self._mixer.deassign_all()
			self._selected_session.deassign_all()
			self._session.deassign_all()
			self.set_highlighting_session_component(self._session)
			self._session._do_show_highlight()
			self._user_mode_selector.set_enabled(False)
			self._midi_mode_selector.set_enabled(False)
			self._split_mode_selector.set_enabled(False)
			self._sequencer_mode_selector.set_enabled(False)

			for pad in self._touchpad:
				pad.set_on_off_values(127, 0)
				pad.release_parameter()
				pad.use_default_message()
				pad.reset(True)
				pad.set_enabled(True)
				pad._descriptor = '_'
			for pad in self._pad:
				pad.display_press = False
				pad.set_on_off_values(127, 0)
				pad.release_parameter()
				pad.use_default_message()
				pad.reset(True)
				pad.set_enabled(True)
				pad._descriptor = '_'
				pad.set_force_next_value()
			for pad in self._pad_CC:
				pad.release_parameter()
				pad.use_default_message()
				pad.set_enabled(True)
			for button in self._button[4:8]:
				button.set_on_off_values(127, 0)
				button.release_parameter()
				button.use_default_message()
				button.reset(True)
				button.set_enabled(True)
				button._descriptor = '_'
			for fader in self._fader[0:8]:
				fader.release_parameter()
				fader.use_default_message()
				fader.send_value(0, True)
				fader.set_enabled(True)
			for runner in self._runner:
				runner.release_parameter()
				runner.reset(True)
				#fader.force_next_send()
		#self.request_rebuild_midi_map()
	

	def _notify_descriptors(self):
		if OSC_TRANSMIT:
			for pad in self._pad:
				self.oscServer.sendOSC(self._prefix+'/'+pad.name+'/lcd_name/', str(self.generate_strip_string(pad._descriptor)))
			for touchpad in self._touchpad:
				self.oscServer.sendOSC(self._prefix+'/'+touchpad.name+'/lcd_name/', str(self.generate_strip_string(touchpad._descriptor)))
			for button in self._button:
				self.oscServer.sendOSC(self._prefix+'/'+button.name+'/lcd_name/', str(self.generate_strip_string(button._descriptor)))
	

	def _set_device_attribute(self, device, attribute, value, force = False):
		if not device is None and hasattr(device, 'name'):
			name = device.name.split(' ')
			for index in range(len(name)):
				if len(str(name[index])) and str(name[index][0])=='@':
					vals = name[index][1:].split(':')
					if vals[0] == attribute:
						#vals[1] = value
						name[index] = str('@'+str(attribute)+':'+str(value))
						device.name = ' '.join(name)
	

	def _top_device(self):
		selected_device = self._device._device
		if not selected_device is None and hasattr(selected_device, 'canonical_parent'):
			while not isinstance(selected_device.canonical_parent, Live.Track.Track):
				selected_device = selected_device.canonical_parent
		return selected_device
	

	def _detect_instrument_type(self, track):
		scale = DEFAULT_AUTO_SCALE
		#for device in self._get_devices(track):
		if self._assign_mod():
			scale = 'Mod'
		else:
			for device in track.devices:
				if isinstance(device, Live.Device.Device):
					#self.log_message('device: ' + str(device.class_name))
					if device.class_name == 'DrumGroupDevice':
						scale = 'DrumPad'
						self._step_sequencer.set_drum_group_device(device)
						break
		return scale
	

	def _get_devices(self, track):

		def dig(container_device):
			contained_devices = []
			if container_device.can_have_chains:
				for chain in container_device.chains:
					for chain_device in chain.devices:
						for item in dig(chain_device):
							contained_devices.append(item)
			else:
				contained_devices.append(container_device)
			return contained_devices
		

		devices = []
		for device in track.devices:
			for item in dig(device):
				devices.append(item)
				#self.log_message('appending ' + str(item))
		return devices
	

	@subject_slot('value')
	def _on_duplicate_button_value(self, value):
		#self.log_message('duplicate button value: ' + str(value))
		track = self._mixer.selected_strip()._track
		#track_index = [t for t in self._mixer.tracks_to_use()].index(self._mixer.selected_strip()._track)
		#self._session.selected_scene.clip_slot(track_index)._do_duplicate_clipslot()
		if not value is 0 and not track is None:
			try:
				track.duplicate_clip_slot([s for s in self.song().scenes].index(self.song().view.selected_scene))
				#self._session.selected_scene.clip_slot(track_index)._do_duplicate_clipslot()
			except:
				self.log_message('couldnt duplicate')
				self.log_message('because: ' + str([s for s in self.song().scenes].index(self.song().view.selected_scene)))
	

	@subject_slot('value')
	def _on_new_button_value(self, value):
		#self.log_message('new button value: ' +str(value))
		song = self.song()
		view = song.view
		try:
			selected_track = view.selected_track
			selected_scene_index = list(song.scenes).index(view.selected_scene)
			selected_track.stop_all_clips(False)
			self._jump_to_next_slot(selected_track, selected_scene_index)
		except:
			self.log_message('couldnt create new')
			#self._view_selected_clip_detail()
	

	def _jump_to_next_slot(self, track, start_index):
		song = self.song()
		new_scene_index = self._next_empty_slot(track, start_index)
		song.view.selected_scene = song.scenes[new_scene_index]
	

	def _next_empty_slot(self, track, scene_index):
		song = self.song()
		scene_count = len(song.scenes)
		while track.clip_slots[scene_index].has_clip:
			scene_index += 1
			if scene_index == scene_count:
				song.create_scene(scene_count)
		return scene_index
	

	"""called on timer"""
	def update_display(self):
		super(GuitarWing, self).update_display()
		self._timer = (self._timer + 1) % 256
		self.flash()
	

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

	"""m4l bridge"""
	def _on_device_name_changed(self):
		name = self._device.device_name_data_source().display_string()
		self._monobridge._send('Device_Name', 'lcd_name', str(self.generate_strip_string('Device')))
		self._monobridge._send('Device_Name', 'lcd_value', str(self.generate_strip_string(name)))
		self.touched()
		if OSC_TRANSMIT:
			self.oscServer.sendOSC(self._prefix+'/glob/device/', str(self.generate_strip_string(name)))
	

	def _on_device_bank_changed(self):
		name = 'No Bank'
		if is_device(self._device._device):
			name, _ = self._device._current_bank_details()
		self._monobridge._send('Device_Bank', 'lcd_name', str(self.generate_strip_string('Bank')))
		self._monobridge._send('Device_Bank', 'lcd_value', str(self.generate_strip_string(name)))
		self.touched()
	

	def _on_device_chain_changed(self):
		name = " "
		if is_device(self._device._device) and self._device._device.canonical_parent and isinstance(self._device._device.canonical_parent, Live.Chain.Chain):
			name = self._device._device.canonical_parent.name
		self._monobridge._send('Device_Chain', 'lcd_name', str(self.generate_strip_string('Chain')))
		self._monobridge._send('Device_Chain', 'lcd_value', str(self.generate_strip_string(name)))
		self.touched()
	

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

		ret += ' '
		ret = ret.replace(' ', '_')
		assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
		return ret
	

	def notification_to_bridge(self, name, value, sender):
		#self.log_message('monobridge:' + str(name) + str(value))
		if isinstance(sender, MonoEncoderElement):
			if OSC_TRANSMIT:
				self.oscServer.sendOSC(self._prefix+'/'+sender.name+'/lcd_name/', str(self.generate_strip_string(name)))
				self.oscServer.sendOSC(self._prefix+'/'+sender.name+'/lcd_value/', str(self.generate_strip_string(value)))
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))
		else:
			self._monobridge._send(name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(name, 'lcd_value', str(self.generate_strip_string(value)))
			if OSC_TRANSMIT:
				self.oscServer.sendOSC(self._prefix+'/'+name+'/lcd_name/', str(self.generate_strip_string(name)))
				self.oscServer.sendOSC(self._prefix+'/'+name+'/lcd_value/', str(self.generate_strip_string(value)))
	

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

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

	"""general functionality"""
	def disconnect(self):
		if not self.oscServer is None:
			self.oscServer.shutdown()
		self.oscServer = None
		self.log_message("--------------= GuitarWing log closed =--------------")
		super(GuitarWing, self).disconnect()
	

	"""some cheap overrides"""

	"""def set_highlighting_session_component(self, session_component):
		self._highlighting_session_component = session_component
		self._highlighting_session_component.set_highlighting_callback(self._set_session_highlight)"""
	

	def handle_sysex(self, midi_bytes):
		#self.log_message('sysex: ' + str(midi_bytes))
		if len(midi_bytes) > 14:
			if midi_bytes[:6] == tuple([240, 0, 1, 97, 12, 64]):
				self._register_pad_pressed(midi_bytes[6:14])
			elif midi_bytes[3:10] == tuple([6, 2, 0, 1, 97, 1, 0]):
				if not self._connected:
					self._connected = True
					self._initialize_hardware()
	

	def _on_selected_track_changed(self):
		super(GuitarWing, self)._on_selected_track_changed()
		track = self._mixer.selected_strip()._track
		track_list = []
		for t in self._mixer.tracks_to_use():
			track_list.append(t)
		if self._last_selected_track and self._last_selected_track.can_be_armed and not self._last_selected_track_arm:
			self.schedule_message(1, self._disarm_track, self._last_selected_track)
			self.schedule_message(1, self._arm_current_track, track)
		if track.can_be_armed:
			self._last_selected_track_arm = track.arm
		self._last_selected_track = track

	def _arm_current_track(self, track):
		track.arm = 1
	

	def _disarm_track(self, track):
		track.arm = 0
	

#	a
Example #13
0
class AumPC40(APC):
	__doc__ = " Script for Akai's APC40 Controller "


	def __init__(self, c_instance, *a, **k):
		super(AumPC40, self).__init__(c_instance, *a, **k)
		self._device_selection_follows_track_selection = True
	

	def _setup_session_control(self):
		is_momentary = True
		self._shift_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 98, 'Shift_Button', self)		   
		right_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 96, 'Right_Button', self)
		self._right_button = right_button
		left_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 97, 'Left_Button', self)
		self._left_button = left_button
		up_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 94, 'Up_Button', self)
		self._up_button = up_button
		down_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 95, 'Down_Button', self)
		self._down_button = down_button
		self._session = PedaledSessionComponent(8, 5)
		self._session.name = 'Session_Control'
		self._session.set_track_bank_buttons(right_button, left_button)
		self._session.set_scene_bank_buttons(down_button, up_button)
		matrix = ButtonMatrixElement()
		self._matrix = matrix  # added a
		matrix.name = 'Button_Matrix'
		scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82)) for index in range(5) ]
		track_stop_buttons = [ AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52, 'Track_' + str(index) + '_Stop_Button', self) for index in range(8) ]
		self._track_stop_buttons = track_stop_buttons  # added a
		for index in range(len(scene_launch_buttons)):
			scene_launch_buttons[index].name = 'Scene_'+ str(index) + '_Launch_Button'
		stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
		stop_all_button.name = 'Stop_All_Clips_Button'
		self._session.set_stop_all_clips_button(stop_all_button)
		self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		self._session.set_stop_track_clip_value(2)
		for scene_index in range(5):
			scene = self._session.scene(scene_index)
			scene.name = 'Scene_' + str(scene_index)
			button_row = []
			scene.set_launch_button(scene_launch_buttons[scene_index])
			scene.set_triggered_value(2)
			for track_index in range(8):
				button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track_index, (scene_index + 53), str(track_index) + '_Clip_' + str(scene_index) + '_Button', self)
				#button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
				button_row.append(button)
				clip_slot = scene.clip_slot(track_index)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				clip_slot.set_triggered_to_play_value(2)
				clip_slot.set_triggered_to_record_value(4)
				clip_slot.set_stopped_value(5)
				clip_slot.set_started_value(1)
				clip_slot.set_recording_value(3)
				clip_slot.set_launch_button(button)
			matrix.add_row(tuple(button_row))
		self._session.set_slot_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
		self._session.selected_scene().name = 'Selected_Scene'
		self._session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
		self._session_zoom = SessionZoomingComponent(self._session)
		self._session_zoom.name = 'Session_Overview'
		self._session_zoom.set_button_matrix(matrix)
		self._session_zoom.set_zoom_button(self._shift_button)
		self._session_zoom.set_nav_buttons(up_button, down_button, left_button, right_button)
		self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
		self._session_zoom.set_stopped_value(3)
		self._session_zoom.set_selected_value(5)
	

	def _setup_mixer_control(self):
		is_momentary = True
		self._mixer = SpecialMixerComponent(8)
		self._mixer.name = 'Mixer'
		self._mixer.master_strip().name = 'Master_Channel_Strip'
		self._mixer.selected_strip().name = 'Selected_Channel_Strip'
		self._solo_buttons = []	# added a
		self._select_buttons = []	# added a
		for track in range(8):
			strip = self._mixer.channel_strip(track)
			strip.name = 'Channel_Strip_' + str(track)
			volume_control = EncoderElement(MIDI_CC_TYPE, track, 7, Live.MidiMap.MapMode.absolute) # 'Slider_' + str(track), track, self)
			arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48)
			solo_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50, str(track) + '_Solo_Button', self)
			self._solo_buttons.append(solo_button)	# added a
			mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49)
			select_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51, str(track) + '_Select_Button', self)
			self._select_buttons.append(select_button)	# added a
			#volume_control.name = str(track) + '_Volume_Control'
			arm_button.name = str(track) + '_Arm_Button'
			#solo_button.name = str(track) + '_Solo_Button'
			mute_button.name = str(track) + '_Mute_Button'
			#select_button.name = str(track) + '_Select_Button'
			strip.set_volume_control(volume_control)
			strip.set_arm_button(arm_button)
			strip.set_solo_button(solo_button)
			strip.set_mute_button(mute_button)
			strip.set_select_button(select_button)
			strip.set_shift_button(self._shift_button)
			strip.set_invert_mute_feedback(True)
		crossfader = SliderElement(MIDI_CC_TYPE, 0, 15)
		self._crossfader = crossfader
		self._crossfader.name = 'Crossfader'
		master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
		master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80)
		self._master_select_button = master_select_button
		prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
		crossfader.name = 'Crossfader'
		master_volume_control.name = 'Master_Volume_Control'
		master_select_button.name = 'Master_Select_Button'
		prehear_control.name = 'Prehear_Volume_Control'
		self._mixer.set_crossfader_control(crossfader)
		self._mixer.set_prehear_volume_control(prehear_control)
		self._mixer.master_strip().set_volume_control(master_volume_control)
		self._mixer.master_strip().set_select_button(master_select_button)
	

	def _setup_custom_components(self):
		self._setup_device_and_transport_control()
		self._setup_global_control()
	

	def _setup_device_and_transport_control(self):
		is_momentary = True
		device_bank_buttons = []
		device_param_controls = []
		bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button', 'Detail_View_Button', 'Rec_Quantization_Button', 'Midi_Overdub_Button', 'Metronome_Button')
		for index in range(8):
			device_bank_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 58 + index))
			device_bank_buttons[-1].name = bank_button_labels[index]
			ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 24 + index)
			ringed_encoder = MonoRingedEncoderElement(MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute, index, self)
			ringed_encoder.set_ring_mode_button(ring_mode_button)
			ringed_encoder.name = 'Device_Control_' + str(index)
			ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
			device_param_controls.append(ringed_encoder)
		device = ShiftableDeviceComponent()
		device.name = 'Device_Component'
		device.set_bank_buttons(tuple(device_bank_buttons))
		device.set_shift_button(self._shift_button)
		device.set_parameter_controls(tuple(device_param_controls))
		device.set_on_off_button(device_bank_buttons[1])
		self.set_device_component(device)
		self._device = device
		detail_view_toggler = DetailViewCntrlComponent()
		detail_view_toggler.name = 'Detail_View_Control'
		detail_view_toggler.set_shift_button(self._shift_button)
		detail_view_toggler.set_device_clip_toggle_button(device_bank_buttons[0])
		detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4])
		detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2], device_bank_buttons[3])
		transport = ShiftableTransportComponent()
		transport.name = 'Transport'
		self._transport = transport
		play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 91)
		stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 92)
		record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 93)
		nudge_up_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 100, 'Nudge_Up_Button', self)
		self._nudge_up_button = nudge_up_button
		nudge_down_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 101, 'Nudge_Down_Button', self)
		self._nudge_down_button = nudge_down_button
		tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99)
		play_button.name = 'Play_Button'
		stop_button.name = 'Stop_Button'
		record_button.name = 'Record_Button'
		#nudge_up_button.name = 'Nudge_Up_Button'
		#nudge_down_button.name = 'Nudge_Down_Button'
		tap_tempo_button.name = 'Tap_Tempo_Button'
		transport.set_shift_button(self._shift_button)
		transport.set_play_button(play_button)
		transport.set_stop_button(stop_button)
		transport.set_record_button(record_button)
		transport.set_nudge_buttons(nudge_up_button, nudge_down_button)
		transport.set_tap_tempo_button(tap_tempo_button)
		transport.set_quant_toggle_button(device_bank_buttons[5])
		transport.set_overdub_button(device_bank_buttons[6])
		transport.set_metronome_button(device_bank_buttons[7])
		bank_button_translator = ShiftTranslatorComponent()
		bank_button_translator.set_controls_to_translate(tuple(device_bank_buttons))
		bank_button_translator.set_shift_button(self._shift_button)
	

	def _setup_global_control(self):
		is_momentary = True
		global_bank_buttons = []
		global_param_controls = []
		for index in range(8):
			ring_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 56 + index)
			ringed_encoder = MonoRingedEncoderElement(MIDI_CC_TYPE, 0, 48 + index, Live.MidiMap.MapMode.absolute, index + 8, self)
			ringed_encoder.name = 'Track_Control_' + str(index)
			ring_button.name = ringed_encoder.name + '_Ring_Mode_Button'
			ringed_encoder.set_ring_mode_button(ring_button)
			global_param_controls.append(ringed_encoder)
		global_bank_buttons = []
		global_bank_labels = ('Pan_Button', 'Send_A_Button', 'Send_B_Button', 'Send_C_Button')
		for index in range(4):
			global_bank_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 87 + index))
			global_bank_buttons[-1].name = global_bank_labels[index]
		encoder_modes = EncModeSelectorComponent(self._mixer)
		encoder_modes.name = 'Track_Control_Modes'
		encoder_modes.set_modes_buttons(global_bank_buttons)
		encoder_modes.set_controls(tuple(global_param_controls))
		global_translation_selector = ChannelTranslationSelector()
		global_translation_selector.name = 'Global_Translations'
		global_translation_selector.set_controls_to_translate(tuple(global_param_controls))
		global_translation_selector.set_mode_buttons(tuple(global_bank_buttons))
	

	def _product_model_id_byte(self):
		return 115
	

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

	def _setup_monomod(self):
		self._host = MonomodComponent(self)
		self._host.name = 'Monomod_Host'
		self._host._navbox_selected = 16
		self._host._navbox_unselected = 1
		self.hosts = [self._host]
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		for row in range(5):
			button_row = []
			for column in range(8):
				button_row.append(self._matrix.get_button(column, row))
			self._monomod.add_row(tuple(button_row))
		self._monomod.add_row(tuple(self._track_stop_buttons))
		self._monomod.add_row(tuple(self._select_buttons))
		self._monomod.add_row(tuple(self._solo_buttons))
		self._monomod_mode = MonomodModeComponent(self._monomod_mode_update, self)
		self._monomod_mode.name = "Monomod_Mode_Component"
		self._shift_button.add_value_listener(self._shift_value)
	

	def _shift_value(self, value):
		if value > 0:
			self._mixer.master_strip().set_select_button(None)
			self._monomod_mode.set_mode_toggle(self._master_select_button)
		else:
			self._mixer.master_strip().set_select_button(self._master_select_button)
			self._monomod_mode.set_mode_toggle(None)
	

	def _monomod_mode_update(self):
		#self.log_message('mode update: ' + str(self._monomod_mode._mode_index))
		if(self._monomod_mode._mode_index == 0) or (self._host._active_client == None):
			self.flash_status = 0
			self._host.set_enabled(False)
			self._host._set_button_matrix(None)
			self._host._set_nav_buttons(None)
			self._host._set_lock_button(None)
			self._host._set_alt_button(None)
			self._host._set_shift_button(None)
			self._monomod.reset()
			self._session.set_track_bank_buttons(self._right_button, self._left_button)
			self._session.set_scene_bank_buttons(self._down_button, self._up_button)
			for track in range(8):
				self._mixer.channel_strip(track).set_select_button(self._select_buttons[track])
				self._mixer.channel_strip(track).set_solo_button(self._solo_buttons[track])
			self._transport.set_nudge_buttons(self._nudge_up_button, self._nudge_down_button)
			self._session.set_enabled(True)
			self._session_zoom._is_zoomed_out = False
			self._session_zoom.set_enabled(True)
			self.request_rebuild_midi_map()
			self._master_select_button.turn_off()
			
		elif(self._monomod_mode._mode_index == 1):
			self._transport.set_nudge_buttons(None, None)
			for track in range(8):
				self._mixer.channel_strip(track).set_select_button(None)
				self._mixer.channel_strip(track).set_solo_button(None)
			self._session.set_enabled(False)
			self._session_zoom.set_enabled(False)
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)
			self.flash_status = 1
			self._monomod.reset()
			self._host._set_button_matrix(self._monomod)
			self._host._set_nav_buttons([self._up_button, self._down_button, self._left_button, self._right_button])
			self._host._set_shift_button(self._shift_button)
			self._host._set_lock_button(self._nudge_up_button)
			self._host._set_alt_button(self._nudge_down_button)
			self._host.set_enabled(True)
			self.request_rebuild_midi_map()
			self._master_select_button.turn_on()
			#self.log_message('mod mode')
	

	"""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, (MonoRingedEncoderElement, MonoEncoderElement)):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))
	

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

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

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

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

	def flash(self):
		if self.flash_status:
			for control in self.controls:
				if isinstance(control, MonoButtonElement):
					control.flash(self._timer)
Example #14
0
File: Cntrlr.py Project: aumhaa/mod
class Cntrlr(ControlSurface):
	__module__ = __name__
	__doc__ = " Monomodular controller script for Livid CNTRLR "


	def __init__(self, *a, **k):
		super(Cntrlr, self).__init__(*a, **k)
		self._version_check = 'b996'
		self._host_name = 'Cntrlr'
		self._color_type = 'OhmRGB'
		self._client = [None for index in range(4)]
		self._active_client = None
		self._rgb = 0
		self._timer = 0
		self._touched = 0
		self.flash_status = 1
		self._skin = Skin(CntrlrColors)
		self._device_selection_follows_track_selection = FOLLOW
		with self.component_guard():
			self._setup_monobridge()
			self._setup_controls()
			self._define_sysex()
			self._setup_transport_control()
			self._setup_autoarm()
			self._setup_session_recording_component()
			self._setup_mixer_control()
			self._setup_send_resets()
			self._setup_session_control()
			self._setup_device_control()
			self._setup_device_selector()
			self._setup_translations()
			self._setup_viewcontrol()
			self._setup_mod()
			self._setup_instrument()
			self._setup_modswitcher()
			self._setup_modes() 
			self._setup_m4l_interface()
			self._on_device_changed.subject = self.song()
			self.set_feedback_channels(range(14, 15))
		self._main_modes.selected_mode = 'MixMode'
		self.schedule_message(1, self._open_log)
	

	def _open_log(self):
		self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) + " " + str(self._version_check) + " log opened =>>>>>>>>>>>>>>>>>>>") 
		self.show_message(str(self._host_name) + ' Control Surface Loaded')
	

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

	def _setup_controls(self):
		is_momentary = True 
		self._fader = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self) for index in range(8)]
		self._dial_left = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_KNOBS_LEFT[index], Live.MidiMap.MapMode.absolute, 'Dial_Left_' + str(index), CNTRLR_KNOBS_LEFT[index], self) for index in range(12)]
		self._dial_right = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_KNOBS_RIGHT[index], Live.MidiMap.MapMode.absolute, 'Dial_Right_' + str(index), CNTRLR_KNOBS_RIGHT[index], self) for index in range(12)]
		self._encoder = [CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), CNTRLR_DIALS[index], self) for index in range(12)] 
		self._encoder_button = [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CNTRLR_DIAL_BUTTONS[index], name = 'Encoder_Button_' + str(index), script = self, skin = self._skin) for index in range(12)]	
		self._grid = [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CNTRLR_GRID[index], name = 'Grid_' + str(index), script = self, skin = self._skin) for index in range(16)]
		self._button = [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CNTRLR_BUTTONS[index], name = 'Button_' + str(index), script = self, skin = self._skin) for index in range(32)]
		self._knobs = self._dial_left + self._dial_right

		self._fader_matrix = ButtonMatrixElement(name = 'Fader_Matrix', rows = [self._fader])
		self._matrix = ButtonMatrixElement(name = 'Matrix', rows = [self._grid[index*4:(index*4)+4] for index in range(4)])
		self._knob_left_matrix = ButtonMatrixElement(name = 'Knob_Left_Matrix', rows = [self._dial_left[index*4:(index*4)+4] for index in range(3)])
		self._knob_right_matrix = ButtonMatrixElement(name = 'Knob_Right_Matrix', rows = [self._dial_right[index*4:(index*4)+4] for index in range(3)])
		self._dial_matrix = ButtonMatrixElement(name = 'Dial_Matrix', rows = [self._encoder[index*4:(index*4)+4] for index in range(3)])
		self._dial_button_matrix = ButtonMatrixElement(name = 'Dial_Button_Matrix', rows = [self._encoder_button[index*4:(index*4)+4] for index in range(1,3)])
		self._key_matrix = ButtonMatrixElement(name = 'Key_Matrix', rows = [self._button[0:16], self._button[16:32]])
		
		self._translated_controls = self._fader + self._knobs + self._encoder[4:] + self._grid + self._button
	

	def _define_sysex(self):
		self.encoder_navigation_on = SendSysexMode(script = self, sysex = (240, 0, 1, 97, 8, 17, 15, 0, 0, 0, 0, 0, 0, 0, 247))
		self.encoder_navigation_off = SendSysexMode(script = self, sysex = (240, 0, 1, 97, 8, 17, 0, 0, 0, 0, 0, 0, 0, 0, 247))
	

	def _setup_transport_control(self):
		self._transport = CntrlrTransportComponent() 
		self._transport.name = 'Transport'
		self._transport.layer = Layer(priority = 4,
									play_button = self._button[28],
									record_button = self._button[30],
									stop_button = self._button[29])
	

	def _setup_autoarm(self):
		self._auto_arm = AutoArmComponent(name='Auto_Arm')
		self._auto_arm.can_auto_arm_track = self._can_auto_arm_track
	

	def _setup_session_recording_component(self):
		self._clip_creator = ClipCreator()
		self._clip_creator.name = 'ClipCreator'
		self._recorder = CntrlrSessionRecordingComponent(self._clip_creator, ViewControlComponent()) # is_enabled = False)
		self._recorder.layer = Layer(priority = 4, new_button = self._button[28], record_button = self._button[29], automation_button = self._button[30])
		self._recorder.set_enabled(False)
	

	def _setup_mixer_control(self):
		is_momentary = True
		self._num_tracks = (4)
		self._mixer = MixerComponent(num_tracks = 4, num_returns = 2, name = 'Mixer', auto_name = True, invert_mute_feedback = True)
		self._mixer.set_track_offset(0)
		if self._mixer.channel_strip(0)._track:
			self.song().view.selected_track = self._mixer.channel_strip(0)._track
		self._mixer.main_faders_layer = AddLayerMode(self._mixer, Layer(priority = 4,
											volume_controls = self._fader_matrix.submatrix[:4, :],
											return_controls = self._fader_matrix.submatrix[4:6, :],
											prehear_volume_control = self._fader[6],))
		self._mixer.main_buttons_layer = AddLayerMode(self._mixer, Layer(priority = 4, 
											mute_buttons = self._key_matrix.submatrix[:4, 1:],
											arm_buttons = self._key_matrix.submatrix[4:8, :1],
											solo_buttons = self._key_matrix.submatrix[:4, :1],
											track_select_buttons = self._key_matrix.submatrix[4:8, 1:],))
		self._mixer.stop_layer = AddLayerMode(self._mixer, Layer(priority = 4,
											stop_clip_buttons = self._key_matrix.submatrix[8:12, 1:],))
		self._mixer.main_knobs_layer = AddLayerMode(self._mixer, Layer(priority = 4,
											send_controls = self._knob_left_matrix.submatrix[:, :2],
											pan_controls = self._knob_left_matrix.submatrix[:, 2:],
											eq_gain_controls = self._knob_right_matrix))
		self._mixer.master_fader_layer = AddLayerMode(self._mixer.master_strip(), Layer(priority = 4,
											volume_control = self._fader[7]))
		self._mixer.instrument_buttons_layer = AddLayerMode(self._mixer, Layer(priority = 4,
											mute_buttons = self._key_matrix.submatrix[:4, 1:],
											track_select_buttons = self._key_matrix.submatrix[4:8, 1:],))
		self._mixer.dial_nav_layer = AddLayerMode(self._mixer, Layer(priority = 4,
									track_select_dial = self._encoder[3]))
	

	def _setup_send_resets(self):
		self._send_reset = CntrlrResetSendsComponent(self)
		self._send_reset.name = 'Sends_Reset'
		self._send_reset.layer = Layer(buttons = self._key_matrix.submatrix[8:12, :1])
	

	def _setup_session_control(self):
		self._session = CntrlrSessionComponent(num_tracks = 4, num_scenes = 4, name = 'Session', enable_skinning = True, auto_name = True)
		self._session.set_mixer(self._mixer)
		self.set_highlighting_session_component(self._session)
		self._session.layer = Layer(priority = 4, clip_launch_buttons = self._matrix)
		self._session.nav_layer = AddLayerMode(self._session, Layer(priority = 4,
									scene_bank_down_button = self._button[14],
									scene_bank_up_button = self._button[15],
									track_bank_left_button = self._button[12],
									track_bank_right_button = self._button[13]))
		self._session.dial_nav_layer = AddLayerMode(self._session, Layer(priority = 4,
									scene_select_dial = self._encoder[2]))

		self._session_zoom = SessionZoomingComponent(session = self._session, name = 'Session_Overview', enable_skinning = True)  # is_enabled = False)	 #
		self._session_zoom.buttons_layer = AddLayerMode(self._session_zoom, Layer(priority = 4, button_matrix = self._matrix))

		self._session.set_offsets(0, 0)
	

	def _setup_device_control(self):
		self._device_selection_follows_track_selection = FOLLOW
		self._device = DeviceComponent()
		self._device.name = 'Device_Component'
		self._device._is_banking_enabled = self.device_is_banking_enabled(self._device)
		self.set_device_component(self._device)
		self._device.layer = Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:, 1:3], 
											lock_button = self._encoder_button[5],
											on_off_button = self._encoder_button[4],
											bank_prev_button = self._encoder_button[6],
											bank_next_button = self._encoder_button[7])

		self._device_navigator = DeviceNavigator(self._device, self._mixer, self)
		self._device_navigator.name = 'Device_Navigator'
		self._device_navigator.layer = Layer(priority = 4, prev_button = self._encoder_button[8], 
											next_button = self._encoder_button[9], 
											prev_chain_button = self._encoder_button[10], 
											next_chain_button = self._encoder_button[11],)
	

	def _setup_device_selector(self):
		self._device_selector = DeviceSelectorComponent(self)  # is_enabled = False)
		self._device_selector.name = 'Device_Selector'
		self._device_selector.layer = Layer(matrix = self._matrix.submatrix[:, :3])
		self._device_selector.set_enabled(False)
	

	def _setup_translations(self):
		self._translations = TranslationComponent(self._translated_controls, user_channel_offset = 4, channel = 4)	# is_enabled = False)
		self._translations.name = 'TranslationComponent'
		self._translations.layer = Layer(priority = 10,)
		self._translations.selector_layer = AddLayerMode(self._translations, Layer(priority = 10, channel_selector_buttons = self._dial_button_matrix))
		self._translations.set_enabled(False)

		self._optional_translations = CompoundMode(TranslationComponent(controls = self._fader, user_channel_offset = 4, channel = 4, name = 'FaderTranslation', is_enabled = False, layer = Layer(priority = 10)) if FADER_BANKING else None, 
														TranslationComponent(controls = self._knobs, user_channel_offset = 4, channel = 4, name = 'DialTranslation', is_enabled = False, layer = Layer(priority = 10)) if DIAL_BANKING else None)
	

	def _setup_mod(self):
		self.monomodular = get_monomodular(self)
		self.monomodular.name = 'monomodular_switcher'
		self.modhandler = CntrlrModHandler(self) # is_enabled = False)
		self.modhandler.name = 'ModHandler' 
		self.modhandler.set_lock_button(self._encoder_button[1])
		self.modhandler.layer = Layer(priority = 8, cntrlr_encoder_grid = self._dial_matrix,
										cntrlr_encoder_button_grid = self._dial_button_matrix,
										cntrlr_grid = self._matrix,
										cntrlr_keys = self._key_matrix,)
										#parameter_controls = self._dial_matrix)
	

	def _setup_instrument(self):
		self._grid_resolution = self.register_disconnectable(GridResolution())
		self._c_instance.playhead.enabled = True
		self._playhead_element = PlayheadElement(self._c_instance.playhead)
		self._playhead_element.reset()

		self._instrument = CntrlrMonoInstrumentComponent(self, self._skin, grid_resolution = self._grid_resolution, name = 'InstrumentModes') # is_enabled = False)
		#self._instrument.layer = Layer(priority = 10, shift_mode_button = self._button[31])
		self._instrument.shift_button_layer = AddLayerMode(self._instrument, Layer(priority = 5, shift_mode_button = self._button[31]))
		self._instrument.audioloop_layer = LayerMode(self._instrument, Layer(priority = 4, loop_selector_matrix = self._key_matrix.submatrix[:, :1]))
		self._instrument.keypad_shift_layer = AddLayerMode(self._instrument, Layer(priority = 4, 
									scale_up_button = self._button[13], 
									scale_down_button = self._button[12],
									offset_up_button = self._button[11], 
									offset_down_button = self._button[10],
									vertical_offset_up_button = self._button[9],
									vertical_offset_down_button = self._button[8],
									split_button = self._button[14],
									sequencer_button = self._button[15]))
		self._instrument.drumpad_shift_layer = AddLayerMode(self._instrument, Layer(priority = 4, 
									scale_up_button = self._button[13],
									scale_down_button = self._button[12],
									drum_offset_up_button = self._button[11], 
									drum_offset_down_button = self._button[10],
									drumpad_mute_button = self._button[9],
									drumpad_solo_button = self._button[8],
									split_button = self._button[14],
									sequencer_button = self._button[15]))
		self._instrument._keypad.main_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, keypad_matrix = self._matrix))
		self._instrument._keypad.sequencer_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, playhead = self._playhead_element, keypad_matrix = self._matrix, sequencer_matrix = self._key_matrix.submatrix[:,:1]))
		self._instrument._keypad.split_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, keypad_matrix = self._matrix, split_matrix = self._key_matrix.submatrix[:8,:1]))
		self._instrument._keypad.sequencer_shift_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, keypad_matrix = self._matrix, loop_selector_matrix = self._key_matrix.submatrix[:8, :1], quantization_buttons = self._key_matrix.submatrix[:7, 1:], follow_button = self._button[23]))
		self._instrument._drumpad.main_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, drumpad_matrix = self._matrix))
		self._instrument._drumpad.sequencer_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, playhead = self._playhead_element, drumpad_matrix = self._matrix, sequencer_matrix = self._key_matrix.submatrix[:,:1]))
		self._instrument._drumpad.split_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, drumpad_matrix = self._matrix, split_matrix = self._key_matrix.submatrix[:8,:1]))
		self._instrument._drumpad.sequencer_shift_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, drumpad_matrix = self._matrix, loop_selector_matrix = self._key_matrix.submatrix[:8, :1], quantization_buttons = self._key_matrix.submatrix[:7, 1:], follow_button = self._button[23]))
		self._instrument.set_enabled(False)
	

	def _setup_modswitcher(self):
		self._modswitcher = ModesComponent(name = 'ModSwitcher')  # is_enabled = False)
		#self._modswitcher.add_mode('instrument', [self._optional_translations])
		self._modswitcher.add_mode('mod', [self.modhandler, self._optional_translations])
		self._modswitcher.add_mode('instrument', [self._instrument, self._instrument.shift_button_layer, self._optional_translations])
		self._modswitcher.set_enabled(False)
	

	def _setup_viewcontrol(self):
		self._view_control = ViewControlComponent(name='View_Control')# is_enabled = False)
		self._view_control.main_layer = AddLayerMode(self._view_control, Layer(prev_track_button=self._button[24], 
													next_track_button= self._button[25], 
													next_scene_button=self._button[27], 
													prev_scene_button = self._button[26]))
		#self._view_control.set_enabled(False)
		self._view_control.selector_layer = AddLayerMode(self._view_control, Layer(priority = 8, 
													prev_track_button = self._grid[12], 
													next_track_button = self._grid[13], 
													next_scene_button = self._grid[15], 
													prev_scene_button = self._grid[14]))
	

	def _setup_modes(self):
		main_buttons=CompoundMode(self._mixer.main_buttons_layer, self._mixer.stop_layer, self._transport, self._send_reset, self._session.nav_layer)
		main_buttons_instrument=CompoundMode(self._mixer.main_buttons_layer, self._recorder, self._view_control.main_layer)
		main_faders=CompoundMode(self._mixer.main_faders_layer, self._mixer.master_fader_layer)
		bottom_buttons=CompoundMode(self._mixer.instrument_buttons_layer, self._recorder, self._view_control.main_layer)

		self._instrument._main_modes = ModesComponent(name = 'InstrumentModes')
		self._instrument._main_modes.add_mode('disabled', [main_buttons_instrument, main_faders, self._mixer.main_knobs_layer, self._device, self._session, self._recorder, self._view_control.main_layer, self._send_reset, self._session.nav_layer,])
		self._instrument._main_modes.add_mode('drumpad', [self._instrument._drumpad.main_layer, main_buttons_instrument, self._send_reset, self._session.nav_layer])
		self._instrument._main_modes.add_mode('drumpad_split', [self._instrument._drumpad.split_layer, self._send_reset, self._session.nav_layer])
		self._instrument._main_modes.add_mode('drumpad_sequencer', [self._instrument._drumpad.sequencer_layer, bottom_buttons])
		self._instrument._main_modes.add_mode('drumpad_shifted', [self._instrument._drumpad.main_layer, self._instrument.drumpad_shift_layer, main_buttons_instrument, self._recorder, self._view_control.main_layer])
		self._instrument._main_modes.add_mode('drumpad_split_shifted', [self._instrument._drumpad.split_layer, self._instrument.drumpad_shift_layer, bottom_buttons, self._recorder, self._view_control.main_layer])
		self._instrument._main_modes.add_mode('drumpad_sequencer_shifted', [self._instrument._drumpad.sequencer_shift_layer, self._instrument.drumpad_shift_layer, self._recorder, self._view_control.main_layer])
		self._instrument._main_modes.add_mode('keypad', [self._instrument._keypad.main_layer, main_buttons_instrument, self._send_reset, self._session.nav_layer])
		self._instrument._main_modes.add_mode('keypad_split', [self._instrument._keypad.split_layer, bottom_buttons, self._send_reset, self._session.nav_layer])
		self._instrument._main_modes.add_mode('keypad_sequencer', [self._instrument._keypad.sequencer_layer, bottom_buttons])
		self._instrument._main_modes.add_mode('keypad_shifted', [self._instrument._keypad.main_layer, self._instrument.keypad_shift_layer, main_buttons_instrument, self._recorder, self._view_control.main_layer])
		self._instrument._main_modes.add_mode('keypad_split_shifted', [self._instrument._keypad.split_layer, self._instrument.keypad_shift_layer, bottom_buttons, self._recorder, self._view_control.main_layer])
		self._instrument._main_modes.add_mode('keypad_sequencer_shifted', [self._instrument._keypad.sequencer_shift_layer, self._instrument.keypad_shift_layer, self._recorder, self._view_control.main_layer])
		self._instrument._main_modes.add_mode('audioloop', [self._instrument.audioloop_layer, self._session, bottom_buttons, self._recorder, self._view_control.main_layer])
		self._instrument.register_component(self._instrument._main_modes)
		self._instrument.set_enabled(False)

		self._session_modes = ModesComponent(name = 'SessionModes', is_enabled = False)
		self._session_modes.add_mode('Session', [self._session])
		self._session_modes.add_mode('SessionZoom', [self._session_zoom.buttons_layer], behaviour = BicoloredMomentaryBehaviour(color = 'Session.ZoomOn', off_color = 'Session.ZoomOff'))
		self._session_modes.layer = Layer(priority = 4, SessionZoom_button = self._button[31])
		self._session_modes.selected_mode = 'Session'

		self._main_modes = ModesComponent(name = 'MainModes')
		self._main_modes.add_mode('MixMode', [main_buttons, main_faders, self._mixer.main_knobs_layer, self._device, self._session_modes, self._session.nav_layer,])  # self._session.dial_nav_layer, self._mixer.dial_nav_layer, self.encoder_navigation_on])
		self._main_modes.add_mode('ModSwitcher', [main_faders, self._mixer.main_knobs_layer, self._modswitcher], behaviour = DefaultedBehaviour(default_mode = 'MixMode', color = 'ModeButtons.ModSwitcher', off_color = 'ModeButtons.ModSwitcherDisabled'))
		self._main_modes.add_mode('Translations', [main_faders, self._mixer.main_knobs_layer, self._translations, DelayMode(self._translations.selector_layer)], behaviour = DefaultedBehaviour(default_mode = 'MixMode', color = 'ModeButtons.Translations', off_color = 'ModeButtons.TranslationsDisabled'))
		self._main_modes.add_mode('DeviceSelector', [self._device_selector, main_buttons, main_faders, self._mixer.main_knobs_layer, self._device, self._device_navigator, self._view_control.selector_layer], behaviour = ColoredCancellableBehaviourWithRelease(color = 'ModeButtons.DeviceSelector', off_color = 'ModeButtons.DeviceSelectorDisabled'))
		self._main_modes.layer = Layer(priority = 4, ModSwitcher_button = self._encoder_button[0], Translations_button = self._encoder_button[3], DeviceSelector_button = self._encoder_button[2])
	

	def _setup_m4l_interface(self):
		self._m4l_interface = MonoM4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard, priority = 10)
		self._m4l_interface.name = "M4LInterface"
		self.get_control_names = self._m4l_interface.get_control_names
		self.get_control = self._m4l_interface.get_control
		self.grab_control = self._m4l_interface.grab_control
		self.release_control = self._m4l_interface.release_control
	

	def _can_auto_arm_track(self, track):
		routing = track.current_input_routing
		return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith('Cntrlr Input')
	

	@subject_slot('appointed_device')
	def _on_device_changed(self):
		debug('appointed device changed, script')
		self.schedule_message(2, self._update_modswitcher)
	

	def _on_selected_track_changed(self):
		super(Cntrlr, self)._on_selected_track_changed()
		self.schedule_message(2, self._update_modswitcher)
	

	def _update_modswitcher(self):
		debug('update modswitcher', self.modhandler.active_mod())
		if self.modhandler.active_mod():
			self._modswitcher.selected_mode = 'mod'
		else:
			self._modswitcher.selected_mode = 'instrument'
	

	def reset_controlled_track(self, track = None, *a):
		if not track:
			track = self.song().view.selected_track
		self.set_controlled_track(track)
	

	def set_controlled_track(self, track = None, *a):
		if isinstance(track, Live.Track.Track):
			super(Cntrlr, self).set_controlled_track(track)
		else:
			self.release_controlled_track()
	

	"""called on timer"""
	def update_display(self):
		super(Cntrlr, self).update_display()		#since we are overriding this from the inherited method, we need to call the original routine as well
		self._timer = (self._timer + 1) % 256	#each 100/60ms, increase the self._timer property by one.  Start over at 0 when we hit 256
		self.modhandler.send_ring_leds()	#if local rings are turned off, then we need to send the new values if they've changed			
		self.flash()							#call the flash method below
	

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

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

		ret += ' '
		ret = ret.replace(' ', '_')
		assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
		return ret
	

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

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

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

	def handle_sysex(self, midi_bytes):
		pass
	

	def disconnect(self):
		self.log_message("<<<<<<<<<<<<<<<<<<<<<<<<< " + str(self._host_name) + " log closed >>>>>>>>>>>>>>>>>>>>>>>>>")
		super(Cntrlr, self).disconnect()
	

	def restart_monomodular(self):
		#debug('restart monomodular')
		self.modhandler.disconnect()
		with self.component_guard():
			self._setup_mod()
	

	def _get_num_tracks(self):
		return self.num_tracks
	

	"""a closure fix for banking when we deassign the bank buttons and still want to change bank indexes"""
	def device_is_banking_enabled(self, device):
		def _is_banking_enabled():
			return True
		return _is_banking_enabled
Example #15
0
class Alias(ControlSurface):
    __module__ = __name__
    __doc__ = " Alias 8 controller script "

    def __init__(self, c_instance):
        super(Alias, self).__init__(c_instance)
        with self.component_guard():
            self._host_name = "Alias"
            self._color_type = "OhmRGB"
            self.log_message("--------------= Alias log opened =--------------")
            self._rgb = 0
            self._timer = 0
            self.flash_status = 1
            self._clutch_device_selection = False
            self._touched = 0
            self._update_linked_device_selection = None
            self._setup_monobridge()
            self._setup_controls()
            self._setup_m4l_interface()
            self._setup_mixer_control()
            self._setup_session_control()
            self._setup_mixer_nav()

    """script initialization methods"""

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

    def _setup_controls(self):
        is_momentary = True
        self._fader = [
            MonoEncoderElement(
                MIDI_CC_TYPE,
                CHANNEL,
                ALIAS_FADERS[index],
                Live.MidiMap.MapMode.absolute,
                "Fader_" + str(index),
                index,
                self,
            )
            for index in range(9)
        ]
        self._button = [
            MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, ALIAS_BUTTONS[index], "Button_" + str(index), self)
            for index in range(16)
        ]
        self._dial = [
            MonoEncoderElement(
                MIDI_CC_TYPE,
                CHANNEL,
                ALIAS_DIALS[index],
                Live.MidiMap.MapMode.absolute,
                "Dial_" + str(index),
                index + 8,
                self,
            )
            for index in range(16)
        ]
        self._encoder = MonoEncoderElement(
            MIDI_CC_TYPE, CHANNEL, ALIAS_ENCODER, Live.MidiMap.MapMode.absolute, "Encoder", 0, self
        )

    def _setup_m4l_interface(self):
        self._m4l_interface = M4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard)
        self.get_control_names = self._m4l_interface.get_control_names
        self.get_control = self._m4l_interface.get_control
        self.grab_control = self._m4l_interface.grab_control
        self.release_control = self._m4l_interface.release_control

    def _setup_mixer_control(self):
        is_momentary = True
        self._num_tracks = 8  # A mixer is one-dimensional;
        self._mixer = AliasMixerComponent(8, 0, False, False)
        self._mixer.name = "Mixer"
        self._mixer.set_track_offset(0)  # Sets start point for mixer strip (offset from left)
        for index in range(8):
            self._mixer.channel_strip(index).set_volume_control(self._fader[index])
            self._mixer.channel_strip(index).set_send_controls(tuple([self._dial[index], self._dial[index + 8]]))
            self._mixer.channel_strip(index).set_mute_button(self._button[index])
            self._button[index].set_on_off_values(MUTE_TOG, 0)
            self._mixer.channel_strip(index)._invert_mute_feedback = True
            self._mixer.channel_strip(index).set_arm_button(self._button[index + 8])
            self._button[index + 8].set_on_off_values(REC_TOG, 0)
            self._mixer.channel_strip(index).name = "Mixer_ChannelStrip_" + str(index)
        self._mixer.master_strip().set_volume_control(self._fader[8])
        self.song().view.selected_track = self._mixer.channel_strip(0)._track

    def _setup_session_control(self):
        self._session = SessionComponent(8, 1)
        self._session.set_mixer(self._mixer)
        self.set_highlighting_session_component(self._session)

    def _setup_mixer_nav(self):
        if not self._encoder.value_has_listener(self._nav_change):
            self._encoder.add_value_listener(self._nav_change)

    """shift/zoom methods"""

    def _nav_change(self, value):
        self._session.set_offsets(
            int((float(value) / float(127)) * max(8, len(self._mixer.tracks_to_use()) - 8)), self._session._scene_offset
        )

    """called on timer"""

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

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

    """m4l bridge"""

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

        ret += " "
        ret = ret.replace(" ", "_")
        assert len(ret) == NUM_CHARS_PER_DISPLAY_STRIP
        return ret

    def notification_to_bridge(self, name, value, sender):
        if isinstance(sender, MonoEncoderElement):
            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)

    """general functionality"""

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

    def disconnect(self):
        if self._encoder.value_has_listener(self._nav_change):
            self._encoder.remove_value_listener(self._nav_change)
        self.log_message("--------------= Alias log closed =--------------")
        super(Alias, self).disconnect()
        rebuild_sys()

    def handle_sysex(self, midi_bytes):
        pass

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

    def assign_alternate_mappings(self):
        pass

    def _get_num_tracks(self):
        return self.num_tracks

    def _on_device_changed(self, device):
        # self.log_message('new device ' + str(type(device)))
        if self._update_linked_device_selection != None:
            self._update_linked_device_selection(device)

    def _on_session_offset_changes(self):
        if self._r_function_mode._mode_index in range(0, 3):
            self._mem[int(self._r_function_mode._mode_index)] = self._session2.track_offset()

    def connect_script_instances(self, instanciated_scripts):
        pass
Example #16
0
class AumPC40(APC):
    __doc__ = " Script for Akai's APC40 Controller "

    def __init__(self, c_instance, *a, **k):
        super(AumPC40, self).__init__(c_instance, *a, **k)
        self._device_selection_follows_track_selection = True

    def _setup_session_control(self):
        is_momentary = True
        self._shift_button = AumPCMonoButtonElement(is_momentary,
                                                    MIDI_NOTE_TYPE, 0, 98,
                                                    'Shift_Button', self)
        right_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                              96, 'Right_Button', self)
        self._right_button = right_button
        left_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                             97, 'Left_Button', self)
        self._left_button = left_button
        up_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 94,
                                           'Up_Button', self)
        self._up_button = up_button
        down_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                             95, 'Down_Button', self)
        self._down_button = down_button
        self._session = PedaledSessionComponent(8, 5)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(right_button, left_button)
        self._session.set_scene_bank_buttons(down_button, up_button)
        matrix = ButtonMatrixElement()
        self._matrix = matrix  # added a
        matrix.name = 'Button_Matrix'
        scene_launch_buttons = [
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82))
            for index in range(5)
        ]
        track_stop_buttons = [
            AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52,
                                   'Track_' + str(index) + '_Stop_Button',
                                   self) for index in range(8)
        ]
        self._track_stop_buttons = track_stop_buttons  # added a
        for index in range(len(scene_launch_buttons)):
            scene_launch_buttons[index].name = 'Scene_' + str(
                index) + '_Launch_Button'
        stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
        stop_all_button.name = 'Stop_All_Clips_Button'
        self._session.set_stop_all_clips_button(stop_all_button)
        self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
        self._session.set_stop_track_clip_value(2)
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                button = AumPCMonoButtonElement(
                    is_momentary, MIDI_NOTE_TYPE, track_index,
                    (scene_index + 53),
                    str(track_index) + '_Clip_' + str(scene_index) + '_Button',
                    self)
                #button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                clip_slot.set_triggered_to_play_value(2)
                clip_slot.set_triggered_to_record_value(4)
                clip_slot.set_stopped_value(5)
                clip_slot.set_started_value(1)
                clip_slot.set_recording_value(3)
                clip_slot.set_launch_button(button)
            matrix.add_row(tuple(button_row))
        self._session.set_slot_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        self._session_zoom = SessionZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_button_matrix(matrix)
        self._session_zoom.set_zoom_button(self._shift_button)
        self._session_zoom.set_nav_buttons(up_button, down_button, left_button,
                                           right_button)
        self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
        self._session_zoom.set_stopped_value(3)
        self._session_zoom.set_selected_value(5)

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._solo_buttons = []  # added a
        self._select_buttons = []  # added a
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            volume_control = EncoderElement(
                MIDI_CC_TYPE, track, 7, Live.MidiMap.MapMode.absolute
            )  # 'Slider_' + str(track), track, self)
            arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48)
            solo_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                                 track, 50,
                                                 str(track) + '_Solo_Button',
                                                 self)
            self._solo_buttons.append(solo_button)  # added a
            mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track,
                                        49)
            select_button = AumPCMonoButtonElement(
                is_momentary, MIDI_NOTE_TYPE, track, 51,
                str(track) + '_Select_Button', self)
            self._select_buttons.append(select_button)  # added a
            #volume_control.name = str(track) + '_Volume_Control'
            arm_button.name = str(track) + '_Arm_Button'
            #solo_button.name = str(track) + '_Solo_Button'
            mute_button.name = str(track) + '_Mute_Button'
            #select_button.name = str(track) + '_Select_Button'
            strip.set_volume_control(volume_control)
            strip.set_arm_button(arm_button)
            strip.set_solo_button(solo_button)
            strip.set_mute_button(mute_button)
            strip.set_select_button(select_button)
            strip.set_shift_button(self._shift_button)
            strip.set_invert_mute_feedback(True)
        crossfader = SliderElement(MIDI_CC_TYPE, 0, 15)
        self._crossfader = crossfader
        self._crossfader.name = 'Crossfader'
        master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
        master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                             80)
        self._master_select_button = master_select_button
        prehear_control = EncoderElement(
            MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
        crossfader.name = 'Crossfader'
        master_volume_control.name = 'Master_Volume_Control'
        master_select_button.name = 'Master_Select_Button'
        prehear_control.name = 'Prehear_Volume_Control'
        self._mixer.set_crossfader_control(crossfader)
        self._mixer.set_prehear_volume_control(prehear_control)
        self._mixer.master_strip().set_volume_control(master_volume_control)
        self._mixer.master_strip().set_select_button(master_select_button)

    def _setup_custom_components(self):
        self._setup_device_and_transport_control()
        self._setup_global_control()

    def _setup_device_and_transport_control(self):
        is_momentary = True
        device_bank_buttons = []
        device_param_controls = []
        bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button',
                              'Previous_Device_Button', 'Next_Device_Button',
                              'Detail_View_Button', 'Rec_Quantization_Button',
                              'Midi_Overdub_Button', 'Metronome_Button')
        for index in range(8):
            device_bank_buttons.append(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 58 + index))
            device_bank_buttons[-1].name = bank_button_labels[index]
            ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0,
                                             24 + index)
            ringed_encoder = MonoRingedEncoderElement(
                MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute,
                index, self)
            ringed_encoder.set_ring_mode_button(ring_mode_button)
            ringed_encoder.name = 'Device_Control_' + str(index)
            ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            device_param_controls.append(ringed_encoder)
        device = ShiftableDeviceComponent()
        device.name = 'Device_Component'
        device.set_bank_buttons(tuple(device_bank_buttons))
        device.set_shift_button(self._shift_button)
        device.set_parameter_controls(tuple(device_param_controls))
        device.set_on_off_button(device_bank_buttons[1])
        self.set_device_component(device)
        self._device = device
        detail_view_toggler = DetailViewCntrlComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_shift_button(self._shift_button)
        detail_view_toggler.set_device_clip_toggle_button(
            device_bank_buttons[0])
        detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4])
        detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2],
                                                   device_bank_buttons[3])
        transport = ShiftableTransportComponent()
        transport.name = 'Transport'
        self._transport = transport
        play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 91)
        stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 92)
        record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 93)
        nudge_up_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                                 0, 100, 'Nudge_Up_Button',
                                                 self)
        self._nudge_up_button = nudge_up_button
        nudge_down_button = AumPCMonoButtonElement(is_momentary,
                                                   MIDI_NOTE_TYPE, 0, 101,
                                                   'Nudge_Down_Button', self)
        self._nudge_down_button = nudge_down_button
        tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99)
        play_button.name = 'Play_Button'
        stop_button.name = 'Stop_Button'
        record_button.name = 'Record_Button'
        #nudge_up_button.name = 'Nudge_Up_Button'
        #nudge_down_button.name = 'Nudge_Down_Button'
        tap_tempo_button.name = 'Tap_Tempo_Button'
        transport.set_shift_button(self._shift_button)
        transport.set_play_button(play_button)
        transport.set_stop_button(stop_button)
        transport.set_record_button(record_button)
        transport.set_nudge_buttons(nudge_up_button, nudge_down_button)
        transport.set_tap_tempo_button(tap_tempo_button)
        transport.set_quant_toggle_button(device_bank_buttons[5])
        transport.set_overdub_button(device_bank_buttons[6])
        transport.set_metronome_button(device_bank_buttons[7])
        bank_button_translator = ShiftTranslatorComponent()
        bank_button_translator.set_controls_to_translate(
            tuple(device_bank_buttons))
        bank_button_translator.set_shift_button(self._shift_button)

    def _setup_global_control(self):
        is_momentary = True
        global_bank_buttons = []
        global_param_controls = []
        for index in range(8):
            ring_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0,
                                        56 + index)
            ringed_encoder = MonoRingedEncoderElement(
                MIDI_CC_TYPE, 0, 48 + index, Live.MidiMap.MapMode.absolute,
                index + 8, self)
            ringed_encoder.name = 'Track_Control_' + str(index)
            ring_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            ringed_encoder.set_ring_mode_button(ring_button)
            global_param_controls.append(ringed_encoder)
        global_bank_buttons = []
        global_bank_labels = ('Pan_Button', 'Send_A_Button', 'Send_B_Button',
                              'Send_C_Button')
        for index in range(4):
            global_bank_buttons.append(
                ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 87 + index))
            global_bank_buttons[-1].name = global_bank_labels[index]
        encoder_modes = EncModeSelectorComponent(self._mixer)
        encoder_modes.name = 'Track_Control_Modes'
        encoder_modes.set_modes_buttons(global_bank_buttons)
        encoder_modes.set_controls(tuple(global_param_controls))
        global_translation_selector = ChannelTranslationSelector()
        global_translation_selector.name = 'Global_Translations'
        global_translation_selector.set_controls_to_translate(
            tuple(global_param_controls))
        global_translation_selector.set_mode_buttons(
            tuple(global_bank_buttons))

    def _product_model_id_byte(self):
        return 115

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

    def _setup_monomod(self):
        self._host = MonomodComponent(self)
        self._host.name = 'Monomod_Host'
        self._host._navbox_selected = 16
        self._host._navbox_unselected = 1
        self.hosts = [self._host]
        self._monomod = ButtonMatrixElement()
        self._monomod.name = 'Monomod'
        for row in range(5):
            button_row = []
            for column in range(8):
                button_row.append(self._matrix.get_button(column, row))
            self._monomod.add_row(tuple(button_row))
        self._monomod.add_row(tuple(self._track_stop_buttons))
        self._monomod.add_row(tuple(self._select_buttons))
        self._monomod.add_row(tuple(self._solo_buttons))
        self._monomod_mode = MonomodModeComponent(self._monomod_mode_update,
                                                  self)
        self._monomod_mode.name = "Monomod_Mode_Component"
        self._shift_button.add_value_listener(self._shift_value)

    def _shift_value(self, value):
        if value > 0:
            self._mixer.master_strip().set_select_button(None)
            self._monomod_mode.set_mode_toggle(self._master_select_button)
        else:
            self._mixer.master_strip().set_select_button(
                self._master_select_button)
            self._monomod_mode.set_mode_toggle(None)

    def _monomod_mode_update(self):
        #self.log_message('mode update: ' + str(self._monomod_mode._mode_index))
        if (self._monomod_mode._mode_index == 0) or (self._host._active_client
                                                     == None):
            self.flash_status = 0
            self._host.set_enabled(False)
            self._host._set_button_matrix(None)
            self._host._set_nav_buttons(None)
            self._host._set_lock_button(None)
            self._host._set_alt_button(None)
            self._host._set_shift_button(None)
            self._monomod.reset()
            self._session.set_track_bank_buttons(self._right_button,
                                                 self._left_button)
            self._session.set_scene_bank_buttons(self._down_button,
                                                 self._up_button)
            for track in range(8):
                self._mixer.channel_strip(track).set_select_button(
                    self._select_buttons[track])
                self._mixer.channel_strip(track).set_solo_button(
                    self._solo_buttons[track])
            self._transport.set_nudge_buttons(self._nudge_up_button,
                                              self._nudge_down_button)
            self._session.set_enabled(True)
            self._session_zoom._is_zoomed_out = False
            self._session_zoom.set_enabled(True)
            self.request_rebuild_midi_map()
            self._master_select_button.turn_off()

        elif (self._monomod_mode._mode_index == 1):
            self._transport.set_nudge_buttons(None, None)
            for track in range(8):
                self._mixer.channel_strip(track).set_select_button(None)
                self._mixer.channel_strip(track).set_solo_button(None)
            self._session.set_enabled(False)
            self._session_zoom.set_enabled(False)
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)
            self.flash_status = 1
            self._monomod.reset()
            self._host._set_button_matrix(self._monomod)
            self._host._set_nav_buttons([
                self._up_button, self._down_button, self._left_button,
                self._right_button
            ])
            self._host._set_shift_button(self._shift_button)
            self._host._set_lock_button(self._nudge_up_button)
            self._host._set_alt_button(self._nudge_down_button)
            self._host.set_enabled(True)
            self.request_rebuild_midi_map()
            self._master_select_button.turn_on()
            #self.log_message('mod mode')

    """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, (MonoRingedEncoderElement, MonoEncoderElement)):
            self._monobridge._send(sender.name, 'lcd_name',
                                   str(self.generate_strip_string(name)))
            self._monobridge._send(sender.name, 'lcd_value',
                                   str(self.generate_strip_string(value)))

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

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

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

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

    def flash(self):
        if self.flash_status:
            for control in self.controls:
                if isinstance(control, MonoButtonElement):
                    control.flash(self._timer)
Example #17
0
class AumPC20(APC20):
    def __init__(self, c_instance, *a, **k):
        self._monomod_version = 'b996'
        self._host_name = 'AumPC'
        self._color_type = 'APC'
        self._timer = 0
        self._touched = 0
        self.flash_status = False
        super(AumPC20, self).__init__(c_instance, *a, **k)
        with self.component_guard():
            self._setup_mod()

    def disconnect(self):
        super(AumPC20, self).disconnect()
        rebuild_sys()

    def _create_controls(self):
        make_color_button = partial(make_button, skin=self._skin)
        self._shift_button = make_button(0,
                                         81,
                                         name='Shift_Button',
                                         num=0,
                                         cs=self)
        self._matrix = ButtonMatrixElement(name='Button_Matrix')
        self._scene_launch_buttons_raw = [
            make_color_button(0,
                              index + 82,
                              name='Scene_%d_Launch_Button' % index,
                              num=index,
                              cs=self) for index in xrange(SESSION_HEIGHT)
        ]
        self._track_stop_buttons = [
            make_color_button(index,
                              52,
                              name='Track_%d_Stop_Button' % index,
                              num=index,
                              cs=self) for index in xrange(SESSION_WIDTH)
        ]
        self._matrix_rows_raw = []
        for scene_index in xrange(SESSION_HEIGHT):
            row = [
                make_color_button(
                    track_index,
                    scene_index + 53,
                    name='%d_Clip_%d_Button' % (track_index, scene_index),
                    num=index,
                    cs=self) for track_index in xrange(SESSION_WIDTH)
            ]
            self._matrix_rows_raw.append(row)
            self._matrix.add_row(row)

        self._selected_scene_launch_button = make_pedal_button(
            64, name='Selected_Scene_Launch_Button')
        self._scene_launch_buttons = ButtonMatrixElement(
            rows=[self._scene_launch_buttons_raw])
        self._solo_buttons = [
            make_button(track_index,
                        49,
                        name='%d_Solo_Button' % track_index,
                        num=track_index,
                        cs=self) for track_index in xrange(MIXER_SIZE)
        ]
        self._mute_buttons = [
            make_button(track_index,
                        50,
                        name='%d_Mute_Button' % track_index,
                        num=track_index,
                        cs=self) for track_index in xrange(MIXER_SIZE)
        ]
        self._master_volume_control = make_slider(0,
                                                  14,
                                                  name='Master_Volume_Control',
                                                  num=0,
                                                  script=self)
        self._prehear_control = EncoderElement(MIDI_CC_TYPE,
                                               0,
                                               47,
                                               MapMode.relative_two_compliment,
                                               name='Prehear_Volume_Control',
                                               num=0,
                                               script=self)
        self._master_select_button = make_button(0,
                                                 80,
                                                 name='Master_Select_Button',
                                                 num=index,
                                                 cs=self)
        self._select_buttons = [
            make_button(track_index,
                        51,
                        name='%d_Select_Button' % track_index,
                        num=track_index,
                        cs=self) for track_index in xrange(8)
        ]
        self._arm_buttons = [
            make_button(track_index,
                        48,
                        name='%d_Arm_Button' % track_index,
                        num=track_index,
                        cs=self) for track_index in xrange(8)
        ]
        self._sliders = [
            make_slider(track_index,
                        7,
                        name='%d_Volume_Control' % track_index,
                        num=track_index,
                        script=self) for track_index in xrange(8)
        ]

        self._monomod = ButtonMatrixElement(name='Monomod')
        for row in self._matrix_rows_raw:
            self._monomod.add_row(row)
        self._monomod.add_row(self._track_stop_buttons)
        self._monomod.add_row(self._select_buttons)
        self._monomod.add_row(self._mute_buttons)

        self._setup_monobridge(
        )  #had to put this here b/c the original author foolishly placed assignment methods inside of creation methods...argh.

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

    def _setup_mod(self):
        self.monomodular = get_monomodular(self)
        self.monomodular.name = 'monomodular_switcher'
        self.modhandler = APCModHandler(self)
        self.modhandler.name = 'ModHandler'
        self.modhandler.layer = Layer(
            priority=5,
            grid=self._monomod,
            nav_up_button=self._scene_launch_buttons_raw[2],
            nav_down_button=self._scene_launch_buttons_raw[3],
            lock_button=self._scene_launch_buttons_raw[4],
            shiftlock_button=self._scene_launch_buttons_raw[0],
            alt_button=self._scene_launch_buttons_raw[1],
            shift_button=self._shift_button)
        self.modhandler.set_enabled(False)
        self._monomod_mode = MonomodModeComponent(self._monomod_mode_update,
                                                  self)
        self._monomod_mode.name = "Monomod_Mode_Component"
        self._monomod_mode.layer = Layer(
            priority=5, mode_toggle=self._master_select_button)
        self._on_shift_value.subject = self._shift_button
        self._on_master_value.subject = self._master_select_button

    @subject_slot('value')
    def _on_shift_value(self, value):
        self._monomod_mode.set_enabled(value > 0)

    @subject_slot('value')
    def _on_master_value(self, value):
        if not self._shift_button.is_pressed(
        ) and not self.modhandler.is_enabled():
            self.schedule_message(1, self._shift_modes.update)

    def _monomod_mode_update(self):
        #self.log_message('mode update: ' + str(self._monomod_mode._mode_index))
        if (self._monomod_mode._mode_index == 0):
            self.flash_status = False
            self.modhandler.set_enabled(False)
            self._slider_modes.set_enabled(True)
            self._shift_modes.set_enabled(True)
            self._scene_launch_buttons[2].set_on_off_values(127, 0)
            self._scene_launch_buttons[3].set_on_off_values(127, 0)
            self._monomod.reset()
            self._shift_modes.set_enabled(True)
            for track in range(8):
                self._mixer.channel_strip(track).set_mute_button(
                    self._mute_buttons[track])
            self._session.set_enabled(True)
            self._session_zoom._is_zoomed_out = False
            self._session_zoom.set_enabled(True)
            self._transport.set_enabled(True)
            self.request_rebuild_midi_map()
            self.schedule_message(1, self._shift_modes.update)
        elif (self._monomod_mode._mode_index == 1):
            self._slider_modes.set_enabled(False)
            if self._shift_modes._note_mode_active is True:
                self._shift_modes._mode_callback(ABLETON_MODE)
                self._shift_modes._note_mode_active = False
                self._session_zoom.set_ignore_buttons(False)
                self._shift_modes._transport.update()
                self._shift_modes._on_note_mode_changed()
            self._shift_modes.set_enabled(False)
            self._session.set_clip_launch_buttons(None)
            for track in range(8):
                self._mixer.channel_strip(track).set_select_button(None)
                self._mixer.channel_strip(track).set_mute_button(None)
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)
            for scene in range(5):
                self._scene_launch_buttons[scene].turn_off()
            self._transport.set_enabled(False)
            self._session.set_enabled(False)
            self._session_zoom.set_enabled(False)
            self.flash_status = True
            self._monomod.reset()
            self.modhandler.set_enabled(True)
        self._master_select_button.send_value(self._monomod_mode._mode_index)

    """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, (MonoRingedEncoderElement, MonoEncoderElement)):
            self._monobridge._send(sender.name, 'lcd_name',
                                   str(self.generate_strip_string(name)))
            self._monobridge._send(sender.name, 'lcd_value',
                                   str(self.generate_strip_string(value)))

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

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

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

    def update_display(self):
        super(AumPC20, self).update_display()
        self._timer = (self._timer + 1) % 256
        self.flash()

    def flash(self):
        if self.flash_status:
            for control, _ in self._monomod.iterbuttons():
                if isinstance(control, MonoButtonElement):
                    control.flash(self._timer)
Example #18
0
class DS1(ControlSurface):
    __module__ = __name__
    __doc__ = " DS1 controller script "

    def __init__(self, c_instance):
        super(DS1, self).__init__(c_instance)
        self._connected = False
        self._host_name = 'DS1'
        self.oscServer = None
        self._rgb = 0
        self._timer = 0
        self.flash_status = 1
        self._touched = 0
        self._update_linked_device_selection = None
        self._skin = Skin(DS1Colors)
        with self.component_guard():
            self._setup_monobridge()
            self._setup_controls()
            self._setup_m4l_interface()
            self._define_sysex()
            self._initialize_hardware()
            self._setup_mixer_control()
            self._setup_session_control()
            self._setup_transport_control()
            self._setup_device_control()
            self._setup_session_recording_component()
            #self._setup_translations()
            self._setup_main_modes()
            #self._device.add_device_listener(self._on_new_device_set)
        self.log_message(
            "<<<<<<<<<<<<<<<<<= DS1 log opened =>>>>>>>>>>>>>>>>>>>>>")
        #self.schedule_message(3, self._initialize_hardware)

    """script initialization methods"""

    def _initialize_hardware(self):
        self.local_control_off.enter_mode()
        self.encoder_absolute_mode.enter_mode()
        self.encoder_speed_sysex.enter_mode()

    def _check_connection(self):
        if not self._connected:
            self._send_midi(QUERYSURFACE)
            self.schedule_message(100, self._check_connection)

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

    def _setup_controls(self):
        is_momentary = True
        self._fader = [
            MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, DS1_FADERS[index],
                               Live.MidiMap.MapMode.absolute,
                               'Fader_' + str(index), index, self)
            for index in range(8)
        ]
        for fader in self._fader:
            fader._mapping_feedback_delay = -1
        self._dial = [[
            MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, DS1_DIALS[x][y],
                               Live.MidiMap.MapMode.absolute,
                               'Dial_' + str(x) + '_' + str(y), x + (y * 5),
                               self) for x in range(8)
        ] for y in range(5)]
        for row in self._dial:
            for dial in row:
                dial._mapping_feedback_delay = -1
        self._side_dial = [
            MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, DS1_SIDE_DIALS[x],
                               Live.MidiMap.MapMode.absolute,
                               'Side_Dial_' + str(x), x, self)
            for x in range(4)
        ]
        for dial in self._side_dial:
            dial._mapping_feedback_delay = -1
        self._encoder = [
            MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, DS1_ENCODERS[x],
                               Live.MidiMap.MapMode.absolute,
                               'Encoder_' + str(x), x, self) for x in range(4)
        ]
        for encoder in self._encoder:
            encoder._mapping_feedback_delay = -1
        self._encoder_button = [
            MonoButtonElement(is_momentary,
                              MIDI_NOTE_TYPE,
                              CHANNEL,
                              DS1_ENCODER_BUTTONS[index],
                              'EncoderButton_' + str(index),
                              self,
                              skin=self._skin) for index in range(4)
        ]
        self._master_fader = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL,
                                                DS1_MASTER,
                                                Live.MidiMap.MapMode.absolute,
                                                'MasterFader', 0, self)
        self._button = [
            MonoButtonElement(is_momentary,
                              MIDI_NOTE_TYPE,
                              CHANNEL,
                              DS1_BUTTONS[index],
                              'Button_' + str(index),
                              self,
                              skin=self._skin) for index in range(16)
        ]
        self._grid = [[
            MonoButtonElement(is_momentary,
                              MIDI_NOTE_TYPE,
                              CHANNEL,
                              DS1_GRID[x][y],
                              'Button_' + str(x) + '_' + str(y),
                              self,
                              skin=self._skin) for x in range(3)
        ] for y in range(3)]
        self._dummy = [
            MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, 120 + x,
                               Live.MidiMap.MapMode.absolute,
                               'Dummy_Dial_' + str(x), x, self)
            for x in range(5)
        ]

        self._fader_matrix = ButtonMatrixElement(name='FaderMatrix',
                                                 rows=[self._fader])
        self._top_buttons = ButtonMatrixElement(name='TopButtonMatrix',
                                                rows=[self._button[:8]])
        self._bottom_buttons = ButtonMatrixElement(name='BottomButtonMatrix',
                                                   rows=[self._button[8:]])
        self._dial_matrix = ButtonMatrixElement(name='DialMatrix',
                                                rows=self._dial)
        self._side_dial_matrix = ButtonMatrixElement(name='SideDialMatrix',
                                                     rows=[self._side_dial])
        self._encoder_matrix = ButtonMatrixElement(name='EncoderMatrix',
                                                   rows=[self._encoder])
        self._encoder_button_matrix = ButtonMatrixElement(
            name='EncoderButtonMatrix', rows=[self._encoder_button])
        self._grid_matrix = ButtonMatrixElement(name='GridMatrix',
                                                rows=self._grid)
        self._selected_parameter_controls = ButtonMatrixElement(
            name='SelectedParameterControls',
            rows=[self._dummy + self._encoder[:1] + self._encoder[2:]])

    def _define_sysex(self):
        self._livid_settings = LividSettings(model=16, control_surface=self)
        self.encoder_speed_sysex = SendLividSysexMode(
            livid_settings=self._livid_settings,
            call='set_encoder_mapping',
            message=ENCODER_SPEED)
        self.encoder_absolute_mode = SendLividSysexMode(
            livid_settings=self._livid_settings,
            call='set_encoder_encosion_mode',
            message=[2])
        self.local_control_off = SendLividSysexMode(
            livid_settings=self._livid_settings,
            call='set_local_control',
            message=[0])

        self.main_mode_message = DisplayMessageMode(self, 'Mute/Solo Mode')
        self.select_mode_message = DisplayMessageMode(self, 'Arm/Select Mode')
        self.clip_mode_message = DisplayMessageMode(self, 'Launch/Stop Mode')

    def _setup_autoarm(self):
        self._auto_arm = AutoArmComponent(name='Auto_Arm')
        self._auto_arm.can_auto_arm_track = self._can_auto_arm_track

    def _setup_mixer_control(self):
        self._num_tracks = (8)
        self._mixer = MixerComponent(script=self,
                                     num_tracks=8,
                                     num_returns=4,
                                     invert_mute_feedback=True,
                                     autoname=True)
        self._mixer.name = 'Mixer'
        self._mixer.set_track_offset(0)
        self._mixer.master_strip().set_volume_control(self._master_fader)
        self._mixer.set_prehear_volume_control(self._side_dial[3])
        self._mixer.layer = Layer(volume_controls=self._fader_matrix,
                                  track_select_dial=self._encoder[1])
        self._strip = [self._mixer.channel_strip(index) for index in range(8)]
        for index in range(8):
            self._strip[index].layer = Layer(
                parameter_controls=self._dial_matrix.submatrix[index:index +
                                                               1, :])
        self._mixer.selected_strip().layer = Layer(
            parameter_controls=self._selected_parameter_controls)
        self._mixer.master_strip().layer = Layer(
            parameter_controls=self._side_dial_matrix.submatrix[:3, :])
        self._mixer.main_layer = AddLayerMode(
            self._mixer,
            Layer(solo_buttons=self._bottom_buttons,
                  mute_buttons=self._top_buttons))
        self._mixer.select_layer = AddLayerMode(
            self._mixer,
            Layer(arm_buttons=self._bottom_buttons,
                  track_select_buttons=self._top_buttons))
        self.song().view.selected_track = self._mixer.channel_strip(0)._track
        self._mixer.set_enabled(True)

    def _setup_session_control(self):
        self._session = DS1SessionComponent(num_tracks=8,
                                            num_scenes=1,
                                            auto_name=True,
                                            enable_skinning=True)
        self._session.set_offsets(0, 0)
        self._session.set_mixer(self._mixer)
        self._session.layer = Layer(
            track_select_dial=ComboElement(self._encoder[1],
                                           modifiers=[self._encoder_button[1]
                                                      ]),
            scene_bank_up_button=self._grid[0][1],
            scene_bank_down_button=self._grid[0][2],
            scene_launch_buttons=self._grid_matrix.submatrix[1:2, 1:2])
        self._session.clips_layer = AddLayerMode(
            self._session,
            Layer(clip_launch_buttons=self._top_buttons,
                  stop_track_clip_buttons=self._bottom_buttons))
        self.set_highlighting_session_component(self._session)
        self._session._do_show_highlight()

    def _setup_transport_control(self):
        self._transport = DS1TransportComponent()
        self._transport.name = 'Transport'
        self._transport.layer = Layer(
            stop_button=self._grid[1][0],
            play_button=self._grid[0][0],
            record_button=self._grid[2][0],
        )
        self._transport.set_enabled(True)

    def _setup_device_control(self):
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        self.set_device_component(self._device)
        self._device_navigator = DeviceNavigator(self._device, self._mixer,
                                                 self)
        self._device_navigator.name = 'Device_Navigator'
        #self._device_selection_follows_track_selection = FOLLOW
        self._device.device_name_data_source().set_update_callback(
            self._on_device_name_changed)

    def _setup_session_recording_component(self):
        self._clip_creator = ClipCreator()
        self._clip_creator.name = 'ClipCreator'
        self._recorder = SessionRecordingComponent(self._clip_creator,
                                                   ViewControlComponent())
        self._recorder.set_enabled(True)
        self._recorder.layer = Layer(
            automation_button=self._grid[1][2],
            record_button=self._grid[2][1],
        )

    def _setup_m4l_interface(self):
        self._m4l_interface = M4LInterfaceComponent(
            controls=self.controls,
            component_guard=self.component_guard,
            priority=10)
        self._m4l_interface.name = "M4LInterface"
        self.get_control_names = self._m4l_interface.get_control_names
        self.get_control = self._m4l_interface.get_control
        self.grab_control = self._m4l_interface.grab_control
        self.release_control = self._m4l_interface.release_control

    def _setup_translations(self):
        controls = []
        for control in self.controls:
            controls.append(control)
        self._translations = TranslationComponent(controls, 10)
        self._translations.name = 'TranslationComponent'
        self._translations.set_enabled(False)

    def _setup_OSC_layer(self):
        self._OSC_id = 0
        if hasattr(__builtins__, 'control_surfaces') or (
                isinstance(__builtins__, dict)
                and 'control_surfaces' in __builtins__.keys()):
            for cs in __builtins__['control_surfaces']:
                if cs is self:
                    break
                elif isinstance(cs, DS1):
                    self._OSC_id += 1

        self._prefix = '/Live/DS1/' + str(self._OSC_id)
        self._outPrt = OSC_OUTPORT
        if not self.oscServer is None:
            self.oscServer.shutdown()
        self.oscServer = RemixNet.OSCServer('localhost', self._outPrt,
                                            'localhost', 10001)

    def _setup_main_modes(self):
        self._main_modes = ToggledModesComponent(name='MainModes')
        self._main_modes.add_mode(
            'Main',
            [self._mixer.main_layer, self.main_mode_message],
        )
        self._main_modes.add_mode(
            'Select',
            [self._mixer.select_layer, self.select_mode_message],
        )
        self._main_modes.add_mode(
            'Clips',
            [self._session.clips_layer, self.clip_mode_message],
        )
        self._main_modes.layer = Layer(priority=4,
                                       toggle_button=self._grid[2][2])
        self._main_modes.set_enabled(True)
        self._main_modes.selected_mode = 'Main'

    def _notify_descriptors(self):
        if OSC_TRANSMIT:
            for pad in self._pad:
                self.oscServer.sendOSC(
                    self._prefix + '/' + pad.name + '/lcd_name/',
                    str(self.generate_strip_string(pad._descriptor)))
            for touchpad in self._touchpad:
                self.oscServer.sendOSC(
                    self._prefix + '/' + touchpad.name + '/lcd_name/',
                    str(self.generate_strip_string(touchpad._descriptor)))
            for button in self._button:
                self.oscServer.sendOSC(
                    self._prefix + '/' + button.name + '/lcd_name/',
                    str(self.generate_strip_string(button._descriptor)))

    def _get_devices(self, track):
        def dig(container_device):
            contained_devices = []
            if container_device.can_have_chains:
                for chain in container_device.chains:
                    for chain_device in chain.devices:
                        for item in dig(chain_device):
                            contained_devices.append(item)
            else:
                contained_devices.append(container_device)
            return contained_devices

        devices = []
        for device in track.devices:
            for item in dig(device):
                devices.append(item)
                #self.log_message('appending ' + str(item))
        return devices

    """called on timer"""

    def update_display(self):
        super(DS1, self).update_display()
        self._timer = (self._timer + 1) % 256
        self.flash()

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

    """m4l bridge"""

    def _on_device_name_changed(self):
        name = self._device.device_name_data_source().display_string()
        self._monobridge._send('Device_Name', 'lcd_name',
                               str(self.generate_strip_string('Device')))
        self._monobridge._send('Device_Name', 'lcd_value',
                               str(self.generate_strip_string(name)))
        self.touched()
        if OSC_TRANSMIT:
            self.oscServer.sendOSC(self._prefix + '/glob/device/',
                                   str(self.generate_strip_string(name)))

    def _on_device_bank_changed(self):
        name = 'No Bank'
        if is_device(self._device._device):
            name, _ = self._device._current_bank_details()
        self._monobridge._send('Device_Bank', 'lcd_name',
                               str(self.generate_strip_string('Bank')))
        self._monobridge._send('Device_Bank', 'lcd_value',
                               str(self.generate_strip_string(name)))
        self.touched()

    def _on_device_chain_changed(self):
        name = " "
        if is_device(
                self._device._device
        ) and self._device._device.canonical_parent and isinstance(
                self._device._device.canonical_parent, Live.Chain.Chain):
            name = self._device._device.canonical_parent.name
        self._monobridge._send('Device_Chain', 'lcd_name',
                               str(self.generate_strip_string('Chain')))
        self._monobridge._send('Device_Chain', 'lcd_value',
                               str(self.generate_strip_string(name)))
        self.touched()

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

        ret += ' '
        ret = ret.replace(' ', '_')
        assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
        return ret

    def notification_to_bridge(self, name, value, sender):
        #self.log_message('monobridge:' + str(name) + str(value))
        if isinstance(sender, MonoEncoderElement):
            if OSC_TRANSMIT:
                self.oscServer.sendOSC(
                    self._prefix + '/' + sender.name + '/lcd_name/',
                    str(self.generate_strip_string(name)))
                self.oscServer.sendOSC(
                    self._prefix + '/' + sender.name + '/lcd_value/',
                    str(self.generate_strip_string(value)))
            self._monobridge._send(sender.name, 'lcd_name',
                                   str(self.generate_strip_string(name)))
            self._monobridge._send(sender.name, 'lcd_value',
                                   str(self.generate_strip_string(value)))
        else:
            self._monobridge._send(name, 'lcd_name',
                                   str(self.generate_strip_string(name)))
            self._monobridge._send(name, 'lcd_value',
                                   str(self.generate_strip_string(value)))
            if OSC_TRANSMIT:
                self.oscServer.sendOSC(
                    self._prefix + '/' + name + '/lcd_name/',
                    str(self.generate_strip_string(name)))
                self.oscServer.sendOSC(
                    self._prefix + '/' + name + '/lcd_value/',
                    str(self.generate_strip_string(value)))

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

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

    """general functionality"""

    def disconnect(self):
        if not self.oscServer is None:
            self.oscServer.shutdown()
        self.oscServer = None
        self.log_message("--------------= DS1 log closed =--------------")
        super(DS1, self).disconnect()

    def _can_auto_arm_track(self, track):
        routing = track.current_input_routing
        return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith(
            'DS1 Input')
        #self._main_modes.selected_mode in ['Sends', 'Device'] and

    def _on_selected_track_changed(self):
        super(DS1, self)._on_selected_track_changed()

    def handle_sysex(self, midi_bytes):
        #self.log_message('sysex: ' + str(midi_bytes))
        if len(midi_bytes) > 14:
            if midi_bytes[3:10] == tuple([6, 2, 0, 1, 97, 1, 0]):
                if not self._connected:
                    self._connected = True
                    self._initialize_hardware()


#	a
Example #19
0
class AumPC20(APC20):


	def __init__(self, c_instance, *a, **k):
		self._monomod_version = 'b996'
		self._host_name = 'AumPC'
		self._color_type = 'APC'
		self._timer = 0
		self._touched = 0
		self.flash_status = False
		super(AumPC20, self).__init__(c_instance, *a, **k)
		with self.component_guard():
			self._setup_mod()
	

	def disconnect(self):
		super(AumPC20, self).disconnect()
		rebuild_sys()
	

	def _create_controls(self):
		make_color_button = partial(make_button, skin=self._skin)
		self._shift_button = make_button(0, 81, name='Shift_Button', num = 0, cs = self)
		self._matrix = ButtonMatrixElement(name='Button_Matrix')
		self._scene_launch_buttons_raw = [ make_color_button(0, index + 82, name='Scene_%d_Launch_Button' % index, num = index, cs = self) for index in xrange(SESSION_HEIGHT) ]
		self._track_stop_buttons = [ make_color_button(index, 52, name='Track_%d_Stop_Button' % index, num = index, cs = self) for index in xrange(SESSION_WIDTH) ]
		self._matrix_rows_raw = []
		for scene_index in xrange(SESSION_HEIGHT):
			row = [ make_color_button(track_index, scene_index + 53, name='%d_Clip_%d_Button' % (track_index, scene_index), num = index, cs = self) for track_index in xrange(SESSION_WIDTH) ]
			self._matrix_rows_raw.append(row)
			self._matrix.add_row(row)

		self._selected_scene_launch_button = make_pedal_button(64, name='Selected_Scene_Launch_Button')
		self._scene_launch_buttons = ButtonMatrixElement(rows=[self._scene_launch_buttons_raw])
		self._solo_buttons = [ make_button(track_index, 49, name='%d_Solo_Button' % track_index, num = track_index, cs = self) for track_index in xrange(MIXER_SIZE) ]
		self._mute_buttons = [ make_button(track_index, 50, name='%d_Mute_Button' % track_index, num = track_index, cs = self) for track_index in xrange(MIXER_SIZE) ]
		self._master_volume_control = make_slider(0, 14, name='Master_Volume_Control', num = 0, script = self)
		self._prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, MapMode.relative_two_compliment, name='Prehear_Volume_Control', num = 0, script = self)
		self._master_select_button = make_button(0, 80, name='Master_Select_Button', num = index, cs = self)
		self._select_buttons = [ make_button(track_index, 51, name='%d_Select_Button' % track_index, num = track_index, cs = self ) for track_index in xrange(8) ]
		self._arm_buttons = [ make_button(track_index, 48, name='%d_Arm_Button' % track_index, num = track_index, cs = self) for track_index in xrange(8) ]
		self._sliders = [ make_slider(track_index, 7, name='%d_Volume_Control' % track_index, num = track_index, script = self) for track_index in xrange(8) ]

		self._monomod = ButtonMatrixElement(name = 'Monomod')
		for row in self._matrix_rows_raw:
			self._monomod.add_row(row)
		self._monomod.add_row(self._track_stop_buttons)
		self._monomod.add_row(self._select_buttons)
		self._monomod.add_row(self._mute_buttons)

		self._setup_monobridge()	#had to put this here b/c the original author foolishly placed assignment methods inside of creation methods...argh.
	

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

	def _setup_mod(self):
		self.monomodular = get_monomodular(self)
		self.monomodular.name = 'monomodular_switcher'
		self.modhandler = APCModHandler(self)
		self.modhandler.name = 'ModHandler' 
		self.modhandler.layer = Layer(priority = 5,
										grid = self._monomod,
										nav_up_button = self._scene_launch_buttons_raw[2], 
										nav_down_button = self._scene_launch_buttons_raw[3], 
										lock_button = self._scene_launch_buttons_raw[4],
										shiftlock_button = self._scene_launch_buttons_raw[0],
										alt_button = self._scene_launch_buttons_raw[1],
										shift_button = self._shift_button)
		self.modhandler.set_enabled(False)
		self._monomod_mode = MonomodModeComponent(self._monomod_mode_update, self)
		self._monomod_mode.name = "Monomod_Mode_Component"
		self._monomod_mode.layer = Layer(priority = 5, mode_toggle = self._master_select_button)
		self._on_shift_value.subject = self._shift_button
		self._on_master_value.subject = self._master_select_button
	

	@subject_slot('value')
	def _on_shift_value(self, value):
		self._monomod_mode.set_enabled(value>0)
	

	@subject_slot('value')
	def _on_master_value(self, value):
		if not self._shift_button.is_pressed() and not self.modhandler.is_enabled():
			self.schedule_message(1, self._shift_modes.update)
	

	def _monomod_mode_update(self):
		#self.log_message('mode update: ' + str(self._monomod_mode._mode_index))
		if(self._monomod_mode._mode_index == 0):
			self.flash_status = False
			self.modhandler.set_enabled(False)
			self._slider_modes.set_enabled(True)
			self._shift_modes.set_enabled(True)
			self._scene_launch_buttons[2].set_on_off_values(127, 0)
			self._scene_launch_buttons[3].set_on_off_values(127, 0)
			self._monomod.reset()
			self._shift_modes.set_enabled(True)
			for track in range(8):
				self._mixer.channel_strip(track).set_mute_button(self._mute_buttons[track])
			self._session.set_enabled(True)
			self._session_zoom._is_zoomed_out = False
			self._session_zoom.set_enabled(True)
			self._transport.set_enabled(True)
			self.request_rebuild_midi_map()
			self.schedule_message(1, self._shift_modes.update)
		elif(self._monomod_mode._mode_index == 1):
			self._slider_modes.set_enabled(False)
			if self._shift_modes._note_mode_active is True:
				self._shift_modes._mode_callback(ABLETON_MODE)
				self._shift_modes._note_mode_active = False
				self._session_zoom.set_ignore_buttons(False)
				self._shift_modes._transport.update()
				self._shift_modes._on_note_mode_changed()
			self._shift_modes.set_enabled(False)
			self._session.set_clip_launch_buttons(None)
			for track in range(8):
				self._mixer.channel_strip(track).set_select_button(None)
				self._mixer.channel_strip(track).set_mute_button(None)
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)
			for scene in range(5):
				self._scene_launch_buttons[scene].turn_off()
			self._transport.set_enabled(False)
			self._session.set_enabled(False)
			self._session_zoom.set_enabled(False)
			self.flash_status = True
			self._monomod.reset()
			self.modhandler.set_enabled(True)
		self._master_select_button.send_value(self._monomod_mode._mode_index)
	

	"""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, (MonoRingedEncoderElement, MonoEncoderElement)):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))
	

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

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

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

	def update_display(self):
		super(AumPC20, self).update_display()
		self._timer = (self._timer + 1) % 256
		self.flash()
	

	def flash(self):
		if self.flash_status:
			for control, _ in self._monomod.iterbuttons():
				if isinstance(control, MonoButtonElement):
					control.flash(self._timer)
Example #20
0
class Codec(ControlSurface):
	__module__ = __name__
	__doc__ = " MonoCode controller script "


	def __init__(self, c_instance, *a, **k):
		super(Codec, self).__init__(c_instance, *a, **k)
		self._monomod_version = 'b995'
		self._version_check = 'b995'
		self._host_name = 'Codec'
		self._color_type = 'Monochrome'
		self._link_mixer = LINK_MIXER
		self._hosts = []
		self._linked_script = None
		self._local_ring_control = True
		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
		with self.component_guard():
			#self.local_ring_control(True)
			#self.set_absolute_mode(True)
			self._setup_controls()
			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.set_local_ring_control(1)
			self.song().view.add_selected_track_listener(self._update_selected_device)
			self._initialize_code()
			#self._shift_mode.set_mode(0)
			#self._monomod_mode.set_mode(0)
		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Codec ' + str(self._monomod_version) + ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
		self.show_message('Codec Control Surface Loaded')
		self.request_rebuild_midi_map()
	


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

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

	def _setup_controls(self):
		is_momentary = True
		self._livid = CodecMonoButtonElement(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] = CodecMonoButtonElement(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] = CodecMonoButtonElement(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] = CodecMonoButtonElement(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._mod_mode_update, self)
		self._monomod_mode.name = 'Monomod_Mode'
		self.set_shift_button(self._livid)
		self._shift_mode = ShiftModeComponent(self._shift_update, self) 
		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 = CodecMonomodComponent(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, MonoButtonElement)))
		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.log_message('mod mode: ' + str(abs(self._monomod_mode._mode_index - 1)))
				self._monomod_mode.set_mode(max(0, min(1, 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()):
			with self.component_guard():
				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, MonoButtonElement):
					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):
		#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
Example #21
0
class AumPC20(APC):
	""" Monomodular script for Akai's APC20 Controller """


	def __init__(self, c_instance, *a, **k):
		self._shift_modes = None
		super(AumPC20, self).__init__(c_instance, *a, **k)
	

	def disconnect(self):
		self._shift_modes = None
		super(AumPC20, self).disconnect()
	

	def _activate_combination_mode(self, track_offset, support_devices):
		super(AumPC20, self)._activate_combination_mode(track_offset, support_devices)
		if support_devices:
			self._shift_modes.invert_assignment()
	

	def _setup_session_control(self):
		is_momentary = True
		self._shift_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81, 'Shift_Button', self)
		self._session = APCSessionComponent(8, 5)
		self._session.name = 'Session_Control'
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Button_Matrix'
		scene_launch_buttons = [ AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82), 'Scene_' + str(index) + '_Launch_Button', self) for index in range(5) ]
		self._scene_launch_buttons = scene_launch_buttons
		track_stop_buttons = [ AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52, 'Track_' + str(index) + '_Stop_Button', self) for index in range(8) ]
		self._track_stop_buttons = track_stop_buttons
		for index in range(len(scene_launch_buttons)):
			scene_launch_buttons[index].name = 'Scene_' + str(index) + '_Launch_Button'

		for index in range(len(track_stop_buttons)):
			track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button'

		self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		self._session.set_stop_track_clip_value(2)
		for scene_index in range(5):
			scene = self._session.scene(scene_index)
			scene.name = 'Scene_' + str(scene_index)
			button_row = []
			scene.set_launch_button(scene_launch_buttons[scene_index])
			scene.set_triggered_value(2)
			for track_index in range(8):
				button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track_index, (scene_index + 53), '_Clip_' + str(scene_index) + '_Button', self)
				button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
				button_row.append(button)
				clip_slot = scene.clip_slot(track_index)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				clip_slot.set_triggered_to_play_value(2)
				clip_slot.set_triggered_to_record_value(4)
				clip_slot.set_stopped_value(5)
				clip_slot.set_started_value(1)
				clip_slot.set_recording_value(3)
				clip_slot.set_launch_button(button)

			self._matrix.add_row(tuple(button_row))

		self._session.selected_scene().name = 'Selected_Scene'
		self._session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
		self._session_zoom = ShiftableZoomingComponent(self._session, tuple(track_stop_buttons))
		self._session_zoom.name = 'Session_Overview'
		self._session_zoom.set_button_matrix(self._matrix)
		self._session_zoom.set_zoom_button(self._shift_button)
		self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
		self._session_zoom.set_stopped_value(3)
		self._session_zoom.set_selected_value(5)
	

	def _setup_mixer_control(self):
		is_momentary = True
		self._mixer = SpecialMixerComponent(8)
		self._mixer.name = 'Mixer'
		self._mixer.master_strip().name = 'Master_Channel_Strip'
		self._mixer.selected_strip().name = 'Selected_Channel_Strip'
		self._solo_buttons = []
		for track in range(8):
			strip = self._mixer.channel_strip(track)
			strip.name = 'Channel_Strip_' + str(track)
			solo_button = AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49, str(track) + '_Solo_Button', self)
			self._solo_buttons.append(solo_button)
			mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50)
			solo_button.name = str(track) + '_Solo_Button'
			mute_button.name = str(track) + '_Mute_Button'
			strip.set_solo_button(solo_button)
			strip.set_mute_button(mute_button)
			strip.set_shift_button(self._shift_button)
			strip.set_invert_mute_feedback(True)

		master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
		prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
		master_volume_control.name = 'Master_Volume_Control'
		prehear_control.name = 'Prehear_Volume_Control'
		self._mixer.set_prehear_volume_control(prehear_control)
		self._mixer.master_strip().set_volume_control(master_volume_control)
	

	def _setup_custom_components(self):
		is_momentary = True
		master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80)
		master_select_button.name = 'Master_Select_Button'
		self._master_select_button = master_select_button
		select_buttons = []
		arm_buttons = []
		sliders = []
		for track in range(8):
			select_buttons.append(AumPCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51, str(track) + '_Select_Button', self))
			arm_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48))
			sliders.append(MonoEncoderElement(MIDI_CC_TYPE, track, 7, Live.MidiMap.MapMode.absolute, 'Slider_' + str(track), track, self))
			select_buttons[-1].name = str(track) + '_Select_Button'
			arm_buttons[-1].name = str(track) + '_Arm_Button'
			#sliders[-1].name = str(track) + '_Volume_Control'
		self._select_buttons = select_buttons

		transport = TransportComponent()
		transport.name = 'Transport'
		slider_modes = SliderModesComponent(self._mixer, tuple(sliders))
		slider_modes.name = 'Slider_Modes'
		self._shift_modes = AumPC20ShiftableSelectorComponent(tuple(select_buttons), master_select_button, tuple(arm_buttons), self._matrix, self._session, self._session_zoom, self._mixer, transport, slider_modes, self._send_introduction_message, self)
		self._shift_modes.name = 'Shift_Modes'
		self._shift_modes.set_mode_toggle(self._shift_button)
		self._device = DeviceComponent()
	

	def _product_model_id_byte(self):
		return 123
	

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

	def _setup_monomod(self):
		self._host = AumPC20MonomodComponent(self)
		self._host.name = 'Monomod_Host'
		self._host._navbox_selected = 16
		self._host._navbox_unselected = 1
		self.hosts = [self._host]
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		for row in range(5):
			button_row = []
			for column in range(8):
				button_row.append(self._matrix.get_button(column, row))
			self._monomod.add_row(tuple(button_row))
		self._monomod.add_row(tuple(self._track_stop_buttons))
		self._monomod.add_row(tuple(self._select_buttons))
		self._monomod.add_row(tuple(self._solo_buttons))
		self._monomod_mode = MonomodModeComponent(self._monomod_mode_update, self)
		self._monomod_mode.name = "Monomod_Mode_Component"
		#self._shift_button.add_value_listener(self._shift_value)
	

	def _shift_value(self, value):
		if value > 0:
			self._mixer.master_strip().set_select_button(None)
			self._monomod_mode.set_mode_toggle(self._master_select_button)
		else:
			self._mixer.master_strip().set_select_button(self._master_select_button)
			self._monomod_mode.set_mode_toggle(None)
	

	def _monomod_mode_update(self):
		self.log_message('mode update: ' + str(self._monomod_mode._mode_index))
		if(self._monomod_mode._mode_index == 0) or (self._host._active_client == None):
			self.flash_status = 0
			self._host.set_enabled(False)
			self._host._set_button_matrix(None)
			#self._host._set_nav_buttons(None)
			self._host._set_lock_button(None)
			self._host._set_alt_button(None)
			self._host._set_shift_button(None)
			self._host._set_nav_buttons(None)
			self._scene_launch_buttons[2].set_on_off_values(127, 0)	
			self._scene_launch_buttons[3].set_on_off_values(127, 0)	
			self._monomod.reset()
			self._shift_modes.set_enabled(True)
			#self._session.set_track_bank_buttons(self._right_button, self._left_button)
			#self._session.set_scene_bank_buttons(self._down_button, self._up_button)
			for track in range(8):
				self._mixer.channel_strip(track).set_select_button(self._select_buttons[track])
				self._mixer.channel_strip(track).set_solo_button(self._solo_buttons[track])
			#self._transport.set_nudge_buttons(self._nudge_up_button, self._nudge_down_button)
			self._session.set_enabled(True)
			self._session_zoom._is_zoomed_out = False
			self._session_zoom.set_enabled(True)
			self.request_rebuild_midi_map()
			self._master_select_button.turn_off()
			
		elif(self._monomod_mode._mode_index == 1):
			if self._shift_modes._note_mode_active is True:
				self._shift_modes._mode_callback(ABLETON_MODE)
				self._shift_modes._note_mode_active = False
				self._session_zoom.set_ignore_buttons(False)
				self._shift_modes._transport.update()
				self._shift_modes._on_note_mode_changed()
			#self._transport.set_nudge_buttons(None, None)
			self._shift_modes.set_enabled(False)
			for track in range(8):
				self._mixer.channel_strip(track).set_select_button(None)
				self._mixer.channel_strip(track).set_solo_button(None)
			for scene in range(5):
				self._scene_launch_buttons[scene].turn_off()
			self._session.set_enabled(False)
			self._session_zoom.set_enabled(False)
			#self._session.set_track_bank_buttons(None, None)
			#self._session.set_scene_bank_buttons(None, None)
			self.flash_status = 1
			self._monomod.reset()
			self._host._set_button_matrix(self._monomod)
			#self._host._set_nav_buttons([self._up_button, self._down_button, self._left_button, self._right_button])
			self._host._set_shift_button(self._shift_button)
			self._host._set_lock_button(self._scene_launch_buttons[0])
			self._host._set_alt_button(self._scene_launch_buttons[1])
			self._host._set_nav_buttons([self._scene_launch_buttons[2], self._scene_launch_buttons[3]])
			self._host.set_enabled(True)
			self.request_rebuild_midi_map()
			self._master_select_button.turn_on()
			#self.log_message('mod mode')
	

	"""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, MonoEncoderElement):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))
	

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

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

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

	def update_display(self):
		super(AumPC20, self).update_display()
		self._timer = (self._timer + 1) % 256
		self.flash()
	

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

	def set_appointed_device(self, *a, **k):
		pass
Example #22
0
 def _setup_monobridge(self):
     self._monobridge = MonoBridgeElement(self)
     self._monobridge.name = "MonoBridge"
Example #23
0
class Faderfox(OptimizedControlSurface):
    __module__ = __name__
    __doc__ = " Monomodular controller script for PO10 "

    def __init__(self, *a, **k):
        super(Faderfox, self).__init__(*a, **k)
        self._version_check = '1.0'
        self._host_name = 'Faderfox'
        self._color_type = 'Monochrome'
        self._rgb = 0
        self._timer = 0
        self._touched = 0
        self.flash_status = 1
        self._skin = Skin(FaderfoxColors)
        self._main_modes = None
        with self.component_guard():
            self._setup_monobridge()
            self._setup_controls()
            self._setup_session()
            self._setup_device_control()
            self._setup_device_selector()
            self._setup_modes()
        self._device_selector.select_device(DEFAULT_DEVICE_INDEX)
        self._on_device_changed.subject = self.song()
        self.set_feedback_channels(range(14, 15))
        #self._main_modes.selected_mode = 'MixMode'
        self.schedule_message(1, self._open_log)
        self._session.set_enabled(True)

    def _open_log(self):
        self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) +
                         " " + str(self._version_check) +
                         " log opened =>>>>>>>>>>>>>>>>>>>")
        self.show_message(str(self._host_name) + ' Control Surface Loaded')

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

    def _setup_controls(self):
        is_momentary = True
        self._button = [
            MonoButtonElement(is_momentary,
                              MIDI_NOTE_TYPE,
                              CHANNEL,
                              FADERFOX_BUTTONS[index],
                              name='Button_' + str(index),
                              script=self,
                              skin=self._skin,
                              color_map=COLOR_MAP) for index in range(4)
        ]
        self._encoder = [
            CodecEncoderElement(MIDI_CC_TYPE, CHANNEL,
                                FADERFOX_ENCODERS[index],
                                Live.MidiMap.MapMode.absolute,
                                'Encoder_' + str(index),
                                FADERFOX_ENCODERS[index], self)
            for index in range(4)
        ]

        self._encoder_matrix = ButtonMatrixElement(name='Encoder_Matrix',
                                                   rows=[self._encoder])
        self._button_matrix = ButtonMatrixElement(name='Button_Matrix',
                                                  rows=[self._button[2:]])

    def _setup_session(self):
        self._session = SessionComponent(name='Session_Component',
                                         num_tracks=20,
                                         num_scenes=1)
        self._session._scenes[0].layer = Layer(priority=6,
                                               launch_button=self._button[0])
        self._session.layer = Layer(priority=6,
                                    scene_bank_down_button=self._button[1])
        self.set_highlighting_session_component(self._session)
        self._session.set_show_highlight(True)
        self._session.set_enabled(False)
        self._session._link()

    def _setup_device_control(self):
        self._device = BaseDeviceComponent()
        self._device.layer = Layer(priority=6,
                                   parameter_controls=self._encoder_matrix)
        self._device.set_enabled(True)

    def _setup_device_selector(self):
        self._device_selector = FaderfoxDeviceSelectorComponent(self,
                                                                self._device,
                                                                prefix='@d')
        self._device_selector.layer = Layer(priority=6,
                                            matrix=self._button_matrix)
        self._device_selector.set_enabled(True)

    def _setup_modes(self):
        pass

    def update_display(self):
        super(Faderfox, self).update_display()
        self._timer = (self._timer + 1) % 256
        self.flash()

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

    @subject_slot('appointed_device')
    def _on_device_changed(self):
        debug('appointed device changed, script')

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

        ret += ' '
        ret = ret.replace(' ', '_')
        assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
        return ret

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

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

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

    def disconnect(self):
        self._session._unlink()
        self.log_message("<<<<<<<<<<<<<<<<<<<<<<<<< " + str(self._host_name) +
                         " log closed >>>>>>>>>>>>>>>>>>>>>>>>>")
        super(Faderfox, self).disconnect()


#	a