def _launch_quant_value(self, value): if self.is_enabled(): if self._launch_quant_button is not None: LC2Sysex.log_message('valu' + str(value)) self.song( ).clip_trigger_quantization = Live.Song.Quantization.values[ value]
def _send_routings(self): if self._track_id < 8: if self._track is not None: for id, type in enumerate([self._track.input_routings, self._track.input_sub_routings, self._track.output_routings, self._track.output_sub_routings]): sysex = LC2Sysex('TRACK_ROUTING_LIST') sysex.byte(self._track_id) sysex.byte(id) sysex.byte(min(12, len(type))) for i in range(12): if i < len(type): sysex.trim(type[i], 10) else: sysex.ascii(' ') sysex.send() else: for i in range(4): sysex = LC2Sysex('TRACK_ROUTING_LIST') sysex.byte(self._track_id) sysex.byte(i) sysex.byte(0) for j in range(12): sysex.ascii('') sysex.send()
def _update_lemur(self): if self.is_enabled(): update = 0 sysex = LC2Sysex('CLIP_POSITION') update2 = 0 sysex2 = LC2Sysex('TRACK_METERS') for id, tr in enumerate(self._channel_strips): pos = tr.playing_position() sysex.byte(pos) meter = tr.track_meters() sysex2.byte(meter[0]) sysex2.byte(meter[1]) if self._meter_cache[id * 2] != meter[0]: self._meter_cache[id * 2] = meter[0] update2 = 1 if self._meter_cache[id * 2 + 1] != meter[1]: self._meter_cache[id * 2 + 1] = meter[1] update2 = 1 if self._pos_cache[id] != pos: self._pos_cache[id] = pos update = 1 mmeter = self._master_strip.track_meters() sysex2.byte(mmeter[0]) sysex2.byte(mmeter[1]) if self._meter_cache[16] != mmeter[0]: self._meter_cache[16] = mmeter[0] update2 = 1 if self._meter_cache[17] != mmeter[1]: self._meter_cache[17] = mmeter[1] update2 = 1 if update: sysex.send() if update2: sysex2.send()
def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) LC2Sysex.set_log(self.log_message) if LC2Sysex.l9(): with self.component_guard(): self.do_setup() else: self.do_setup()
def _bank_down(self): if LC2Sysex.l9(): if len(self.song().scenes) > self.scene_offset() + self.height(): SessionComponent._bank_down(self) self.send_offsets() LC2Sysex.log_message(str(len(self.song().scenes)) + ' ' + str(self.scene_offset() + self.height())) if len(self.song().scenes) == self.scene_offset() + self.height(): self._bank_down_button.turn_off()
def set_clip(self, clip, slot): if self._clip is not None: try: if self._clip.playing_position_has_listener( self._on_playing_position_changed): self._clip.remove_playing_position_listener( self._on_playing_position_changed) if self._clip.notes_has_listener(self._on_notes_changed): self._clip.remove_notes_listener(self._on_notes_changed) if self._slot.has_clip_has_listener(self._on_slot_changed): self._slot.remove_has_clip_listener(self._on_slot_changed) for l in self._clisten: chk = getattr(self._clip, l + '_has_listener') if chk(self._on_length_changed): rem = getattr(self._clip, 'remove_' + l + '_listener') rem(self._on_length_changed) except: pass self._clip = clip self._slot = slot if clip is not None: self._clip.add_playing_position_listener( self._on_playing_position_changed) self._clip.add_notes_listener(self._on_notes_changed) self._slot.add_has_clip_listener(self._on_slot_changed) for l in self._clisten: add = getattr(self._clip, 'add_' + l + '_listener') add(self._on_length_changed) LC2Sysex.log_message(str(self._clip.length)) self._quantisation = 0.25 self._time_offset = 0 sysex = LC2Sysex('CLIP_TITLE') sysex.ascii( clip is not None and clip.canonical_parent.canonical_parent.name + ': ' + str( list(clip.canonical_parent.canonical_parent.clip_slots).index( clip.canonical_parent) + 1) + '. ' + (clip.name and clip.name or 'Unnamed') or '') sysex.rgb(clip is not None and clip.color or 0) sysex.send() self._cache_notes() if self._clip is not None: min = 128 for note in self._note_cache: if note[0] < min: min = note[0] self._note_offset = len(self._note_cache) == 0 and 36 or min self._fold_notes = 0 self._save_note = 0 self._send_offsets() self._on_playing_position_changed() self.update() return
def set_clip(self, clip, slot): if self._clip is not None: try: if self._clip.playing_position_has_listener(self._on_playing_position_changed): self._clip.remove_playing_position_listener(self._on_playing_position_changed) if self._clip.notes_has_listener(self._on_notes_changed): self._clip.remove_notes_listener(self._on_notes_changed) if self._slot.has_clip_has_listener(self._on_slot_changed): self._slot.remove_has_clip_listener(self._on_slot_changed) for l in self._clisten: chk = getattr(self._clip, l + "_has_listener") if chk(self._on_length_changed): rem = getattr(self._clip, "remove_" + l + "_listener") rem(self._on_length_changed) except: pass self._clip = clip self._slot = slot if clip is not None: self._clip.add_playing_position_listener(self._on_playing_position_changed) self._clip.add_notes_listener(self._on_notes_changed) self._slot.add_has_clip_listener(self._on_slot_changed) for l in self._clisten: add = getattr(self._clip, "add_" + l + "_listener") add(self._on_length_changed) LC2Sysex.log_message(str(self._clip.length)) self._quantisation = 0.25 self._time_offset = 0 sysex = LC2Sysex("CLIP_TITLE") sysex.ascii( clip is not None and clip.canonical_parent.canonical_parent.name + ": " + str(list(clip.canonical_parent.canonical_parent.clip_slots).index(clip.canonical_parent) + 1) + ". " + (clip.name and clip.name or "Unnamed") or "" ) sysex.rgb(clip is not None and clip.color or 0) sysex.send() self._cache_notes() if self._clip is not None: min = 128 for note in self._note_cache: if note[0] < min: min = note[0] self._note_offset = len(self._note_cache) == 0 and 36 or min self._fold_notes = 0 self._save_note = 0 self._send_offsets() self._on_playing_position_changed() self.update()
def _select_xy(self, sysex): pid = sysex.parse('b') LC2Sysex.log_message('SELECTING XY ' + str(pid)) if pid < len(self._xys): self._selected_param = pid param = self._xys[pid] if param.mapped_parameter() is not None: if isinstance(param.mapped_parameter().canonical_parent, Live.Device.Device): self.song().view.select_device(param.mapped_parameter().canonical_parent) self._send_id_param()
def disconnect(self): self._do_uncombine() if LC2Sysex.l9(): task = self._tasks.find(self._on_time_changed) self._tasks.remove(task) else: self._unregister_timer_callback(self._on_time_changed) self.song().remove_tempo_listener(self._on_tempo_changed) ControlSurface.disconnect(self) LC2Sysex.release_attributes() LC2SessionBank.release_attributes()
def update(self): array = [0 for i in range(self._height)] array_l = [0 for i in range(self._height)] for note in self._note_cache: step = self._step(note[1]) nstep = self._note_step(note[0]) if step in range(16) and nstep in range(self._height): array[self._height - 1 - nstep] |= 1 << step last = self._step(note[1] + note[2]) for j in range(step + 1, min(last, 16)): array_l[self._height - 1 - nstep] |= 1 << j sysex = LC2Sysex("STEPS") for b in array: sysex.int2(b) sysex.send() sysex = LC2Sysex("STEPS2") for b in array_l: sysex.int2(b) sysex.send() sysex = LC2Sysex("SEQ_FADERS") states = 0 for i in range(16): fad = self._get_fader(i)[0] if fad == -1: sysex.byte(0) else: states |= 1 << i sysex.byte(fad) sysex.int2(states) sysex.send() self._get_timeline() self._get_note_line() sysex = LC2Sysex("SEQ_MUTES") mutes = 0 for i in range(self._height): mutes |= self._mutes[self._note(i)] << self._height - 1 - i sysex.int2(mutes) sysex.send() sysex = LC2Sysex("SEQ_FOLD") sysex.byte(self._fold_notes) sysex.send() sysex = LC2Sysex("SEQ_QUANT") sysex.int(int(self._quantisation * 1000)) LC2Sysex.log_message(str(int(self._quantisation * 1000))) sysex.send() sysex = LC2Sysex("SEQ_SAVE_NOTE") sysex.byte(self._save_note) sysex.send()
def bank(self, ud): if self._device is not None: LC2Sysex.log_message('device') if ud: num_banks = self.number_of_parameter_banks(self._device) LC2Sysex.log_message('up' + str(num_banks)) if num_banks > self._bank_index + 1: self._bank_name = '' self._bank_index += 1 self.update() elif self._bank_index > 0: self._bank_name = '' self._bank_index -= 1 self.update()
def bank(self, ud): if self._device is not None: LC2Sysex.log_message('device') if ud: num_banks = self.number_of_parameter_banks(self._device) LC2Sysex.log_message('up' + str(num_banks)) if num_banks > self._bank_index + 1: self._bank_name = '' self._bank_index += 1 self.update() elif self._bank_index > 0: self._bank_name = '' self._bank_index -= 1 self.update()
def handle_sysex(self, sysex): if list(sysex).count(247) == 0: count = 1 else: count = list(sysex).count(247) LC2Sysex.log_message(str(sysex)) LC2Sysex.log_message('sysex count' + str(count)) msysex = [[] for i in range(count + 1)] id = 0 start = list(sysex).index(240) for i, b in enumerate(sysex): if i >= start: msysex[id].append(b) if b == 247: id += 1 LC2Sysex.log_message(str(msysex)) pages = [self._session, self._mixer, self._sequencer, self._modulator] for sysex in msysex: if len(sysex) > 1: if sysex[1] == 5: if sysex[2] == 1: self._init() elif sysex[2] == 2: sysex = LC2SysexParser(sysex[3:]) interface = sysex.parse('b') LC2Sysex.log_message('interface change: ' + str(interface)) if interface == 0 or interface == 1 or interface == 2: self._mixer.set_enabled(1) else: self._mixer.set_enabled(0) elif sysex[1] < len(pages): pages[sysex[1]].handle_sysex(sysex[2:])
def _transpose(self, args): if not self._fold_notes: pitch = args[0] == 1 and 1 or -1 selection, left = self._get_selection() for note in selection: id = self._note_step(note[0]) LC2Sysex.log_message('old ' + str(note[0])) note[0] = self._note(id + pitch) LC2Sysex.log_message('new ' + str(note[0]) + ' ' + str(id)) self._clip.select_all_notes() self._clip.replace_selected_notes(tuple(selection + left)) self._selection[0] += pitch self._selection[1] += pitch self.update()
def _note_press(self, sysex): x, y = sysex.parse("bb") pos = self._pos(x) pos2 = self._pos(x + 1) pitch = self._note(y) found = 0 for note in self._note_cache: if note[1] >= pos and note[1] < pos2 and note[0] == pitch: LC2Sysex.log_message(str(note[1]) + " " + str(pos) + " " + str(pos2)) found = 1 if found: self.rem_note(pos, pos2, pitch) else: self.add_note(pos, pos2, pitch)
def _transpose(self, args): if not self._fold_notes: pitch = args[0] == 1 and 1 or -1 selection, left = self._get_selection() for note in selection: id = self._note_step(note[0]) LC2Sysex.log_message("old " + str(note[0])) note[0] = self._note(id + pitch) LC2Sysex.log_message("new " + str(note[0]) + " " + str(id)) self._clip.select_all_notes() self._clip.replace_selected_notes(tuple(selection + left)) self._selection[0] += pitch self._selection[1] += pitch self.update()
def update(self): array = [0 for i in range(self._height)] array_l = [0 for i in range(self._height)] for note in self._note_cache: step = self._step(note[1]) nstep = self._note_step(note[0]) if step in range(16) and nstep in range(self._height): array[self._height - 1 - nstep] |= 1 << step last = self._step(note[1] + note[2]) for j in range(step + 1, min(last, 16)): array_l[self._height - 1 - nstep] |= 1 << j sysex = LC2Sysex('STEPS') for b in array: sysex.int2(b) sysex.send() sysex = LC2Sysex('STEPS2') for b in array_l: sysex.int2(b) sysex.send() sysex = LC2Sysex('SEQ_FADERS') states = 0 for i in range(16): fad = self._get_fader(i)[0] if fad == -1: sysex.byte(0) else: states |= 1 << i sysex.byte(fad) sysex.int2(states) sysex.send() self._get_timeline() self._get_note_line() sysex = LC2Sysex('SEQ_MUTES') mutes = 0 for i in range(self._height): mutes |= self._mutes[self._note(i)] << self._height - 1 - i sysex.int2(mutes) sysex.send() sysex = LC2Sysex('SEQ_FOLD') sysex.byte(self._fold_notes) sysex.send() sysex = LC2Sysex('SEQ_QUANT') sysex.int(int(self._quantisation * 1000)) LC2Sysex.log_message(str(int(self._quantisation * 1000))) sysex.send() sysex = LC2Sysex('SEQ_SAVE_NOTE') sysex.byte(self._save_note) sysex.send()
def send_xy_map(self): sysex = LC2Sysex('XY_MAP') for p in self._xys: sysex.byte(int(p.mapped_parameter() is not None)) sysex.send() return
def _send_param_val(self, force=False): if self._parameter_to_map_to is not None: if hasattr(self, 'select_parameter'): if self._report_name_val: self.select_parameter(self._parameter_to_map_to) if time.clock() > self._last_time + 0.01 or force: if hasattr(self._parameter_to_map_to, 'name'): sysex = LC2Sysex('PARAM_VALS') if self.message_type() == MIDI_PB_TYPE: sysex.byte(16) sysex.byte(self.message_channel()) else: sysex.byte(self.message_channel()) sysex.byte(self.message_identifier()) if self._parameter_to_map_to is not None: sysex.ascii(unicode(self._parameter_to_map_to.name)) sysex.ascii(unicode(self._parameter_to_map_to)) sysex.byte(self._parameter_to_map_to.is_enabled) else: sysex.ascii(' ') sysex.ascii(' ') sysex.byte(0) self.send_value(0) sysex.send() self._last_time = time.clock()
def _send_states(self): sysex = LC2Sysex('SNAPSHOT_STATES') val = 0 for t in self.get_states(): sysex.byte(t) sysex.send()
def _on_routing_changed(self): if self._track_id < 8: self._send_routings() sysex = LC2Sysex('TRACK_ROUTING') sysex.byte(self._track_id) if self._track is not None: objs = [self._track.input_routings, self._track.current_input_routing, self._track.input_sub_routings, self._track.current_input_sub_routing, self._track.output_routings, self._track.current_output_routing, self._track.output_sub_routings, self._track.current_output_sub_routing] for i in range(4): if objs[i * 2 + 1] in objs[i * 2]: sysex.byte(list(objs[i * 2]).index(objs[i * 2 + 1])) elif objs[i * 2 + 1] == 'None': sysex.byte(len(objs[i * 2]) - 1) else: sysex.byte(127) else: sysex.byte(127) sysex.byte(127) sysex.byte(127) sysex.byte(127) sysex.send()
def _send_chain_devices(self): cdl = 0 if self._device is not None: if hasattr(self._device, 'chains'): if self._selected_chain_id < len(self._device.chains): devices = [ '' for i in range(8) if not (i < len(self._device.chains[ self._selected_chain_id].devices) and self._device. chains[self._selected_chain_id].devices[i].name) ] cdl = min( 8, len(self._device.chains[ self._selected_chain_id].devices)) else: devices = ['' for i in range(8)] else: devices = ['' for i in range(8)] else: devices = ['' for i in range(8)] sysex = LC2Sysex('CHAIN_DEVICES') sysex.byte(cdl) for i in range(8): sysex.ascii(devices[i]) sysex.send()
def __init__(self): ControlSurfaceComponent.__init__(self) self._register_timer_callback(self._on_timer) self._refresh = 0 self._clip = None self._note_cache = [] self._last_note = 36 self._last_pos = 0 self._quantisation = 0.25 self._default_length = 1 self._default_velocity = 100 self._time_offset = 0 self._note_offset = 36 self._num_steps = 16 self._height = 16 self._root = 0 self._scale = 0 self._scales = [[], [0, 2, 4, 5, 7, 9, 11], [0, 2, 3, 5, 7, 8, 10], [0, 2, 3, 5, 7, 8, 11], [0, 2, 4, 7, 9]] self._mutes = [0 for i in range(127)] self._fader_type = 0 self._fold_notes = 0 self._save_note = 0 self._ltime = "" self._chord_intervals = [[0, 4, 7], [0, 3, 7], [0, 4, 8], [0, 4, 6], [0, 3, 6], [0, 5, 7]] self._quick_chord = 127 self._durations = [0.125, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 4] self._selection = [0, 0, 0, 0] self._last_details = [-1, -1, -1, -1, -1] if LC2Sysex.l9(): self._clisten = ("loop_start", "loop_end", "start_marker", "end_marker") else: self._clisten = ("loop_start", "loop_end")
def _send_id_param(self): param = self._xys[self._selected_param] if param.mapped_parameter() is not None: mapped = 1 pid, name = param.settings() else: mapped = 0 if self._selected_parameter is not None: if hasattr(self._selected_parameter, 'canonical_parent'): parent = self._selected_parameter.canonical_parent if not hasattr(parent, 'name'): if hasattr(parent, 'canonical_parent'): parent = parent.canonical_parent pid = unicode(parent.name) name = unicode(self._selected_parameter.name) else: pid = '' name = '' else: pid = '' name = '' sysex = LC2Sysex('XY_ID_NAME') sysex.byte(mapped) sysex.ascii(pid) sysex.ascii(name) sysex.send()
def _bank_right(self): if LC2Sysex.l9(): if len(self.tracks_to_use()) > self.track_offset() + self.width(): SessionComponent._bank_right(self) self.send_offsets() if len(self.tracks_to_use()) == self.track_offset() + self.width(): self._bank_right_button.turn_off()
def _bank_left(self): if LC2Sysex.l9(): if self.track_offset() > 0: SessionComponent._bank_left(self) self.send_offsets() else: self._bank_left_button.turn_off()
def _bank_left(self): if LC2Sysex.l9(): if self.track_offset() > 0: SessionComponent._bank_left(self) self.send_offsets() else: self._bank_left_button.turn_off()
def _note_press(self, sysex): x, y = sysex.parse('bb') pos = self._pos(x) pos2 = self._pos(x + 1) pitch = self._note(y) found = 0 for note in self._note_cache: if note[1] >= pos and note[1] < pos2 and note[0] == pitch: LC2Sysex.log_message( str(note[1]) + ' ' + str(pos) + ' ' + str(pos2)) found = 1 if found: self.rem_note(pos, pos2, pitch) else: self.add_note(pos, pos2, pitch)
def _bank_right(self): if LC2Sysex.l9(): if len(self.tracks_to_use()) > self.track_offset() + self.width(): SessionComponent._bank_right(self) self.send_offsets() if len(self.tracks_to_use()) == self.track_offset() + self.width(): self._bank_right_button.turn_off()
def __init__(self): ControlSurfaceComponent.__init__(self) self._register_timer_callback(self._on_timer) self._refresh = 0 self._clip = None self._note_cache = [] self._last_note = 36 self._last_pos = 0 self._quantisation = 0.25 self._default_length = 1 self._default_velocity = 100 self._time_offset = 0 self._note_offset = 36 self._num_steps = 16 self._height = 16 self._root = 0 self._scale = 0 self._scales = [[], [0, 2, 4, 5, 7, 9, 11], [0, 2, 3, 5, 7, 8, 10], [0, 2, 3, 5, 7, 8, 11], [0, 2, 4, 7, 9]] self._mutes = [0 for i in range(127)] self._fader_type = 0 self._fold_notes = 0 self._save_note = 0 self._ltime = '' self._chord_intervals = [[0, 4, 7], [0, 3, 7], [0, 4, 8], [0, 4, 6], [0, 3, 6], [0, 5, 7]] self._quick_chord = 127 self._durations = [0.125, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 4] self._selection = [0, 0, 0, 0] self._last_details = [-1, -1, -1, -1, -1] if LC2Sysex.l9(): self._clisten = ('loop_start', 'loop_end', 'start_marker', 'end_marker') else: self._clisten = ('loop_start', 'loop_end')
def _send_selection(self, x1=0, x2=0, y1=0, y2=0): sysex = LC2Sysex('SEQ_SEND_SELECTION') sysex.byte(x1) sysex.byte(x2) sysex.byte(y1) sysex.byte(y2) sysex.send()
def _on_time_changed(self): smpt = self.song().get_current_smpte_song_time(0) time = (smpt.hours > 0 and (smpt.hours < 10 and '0' + str(smpt.hours) or str(smpt.hours)) + ':' or '') + (smpt.minutes < 10 and '0' + str(smpt.minutes) or str(smpt.minutes)) + ':' + (smpt.seconds < 10 and '0' + str(smpt.seconds) or str(smpt.seconds)) if time != self._last_time: sysex = LC2Sysex('TIME') sysex.ascii(time) sysex.send() self._last_time = time
def set_device(self, device): DeviceComponent.set_device(self, device) if device is not None: if hasattr(device, 'chains'): LC2Sysex.log_message(str(len(device.chains))) if hasattr(device, 'drum_pads'): LC2Sysex.log_message(str(len(device.drum_pads))) LC2Sysex.log_message(str(len(device.drum_pads[0].chains))) cl = 0 par = False if self._device is not None: if hasattr(self._device, 'canonical_parent'): par = isinstance(self._device.canonical_parent, Live.Device.Device) or isinstance(self._device.canonical_parent, Live.Chain.Chain) else: par = False if hasattr(self._device, 'chains'): if len(self._device.chains) > 0: chains = [ i < len(self._device.chains) and (self._device.chains[i].name == '' and 'Chain ' + str(i + 1) or self._device.chains[i].name) or '' for i in range(8) ] cl = min(8, len(self._device.chains)) else: chains = [ '' for i in range(8) ] else: chains = [ '' for i in range(8) ] else: chains = [ '' for i in range(8) ] sysex = LC2Sysex('CHAIN_NAMES') sysex.byte(cl) sysex.byte(int(par)) for i in range(8): sysex.ascii(chains[i]) sysex.send() self._selected_chain_id = 0 self._send_chain_devices()
def _half(self, args): if self._clip is not None: self._clip.loop_end -= self._clip.length / 2 if LC2Sysex.l9(): if self._clip.end_marker > self._clip.loop_end: self._clip.end_marker = self._clip.loop_end self._time_offset = 0 self.update() self._send_offsets()
def _half(self, args): if self._clip is not None: self._clip.loop_end -= self._clip.length / 2 if LC2Sysex.l9(): if self._clip.end_marker > self._clip.loop_end: self._clip.end_marker = self._clip.loop_end self._time_offset = 0 self.update() self._send_offsets()
def send_sends(self): sysex = LC2Sysex('RETURN_NAMES') sysex.byte(len(self.song().return_tracks)) for i in range(12): if i < len(self.song().return_tracks): sysex.trim(self.song().return_tracks[i].name, 15) else: sysex.ascii('') sysex.send()
def _on_playing_position_changed(self): if self._clip is not None: step = self._step(self._clip.playing_position) if step != self._last_pos: if step not in range(16): step = 16 sysex = LC2Sysex('SEQ_POSITION') sysex.byte(step) sysex.send() self._last_pos = step
def _compress(self, args): sel, rem = self._get_selection() min = 99999 for note in sel: if note[1] < min: min = note[1] for note in sel: LC2Sysex.log_message('before: ' + str(note)) if not args[0]: note[1] = (note[1] - min) / 0.5 + min note[2] = note[2] / 0.5 else: note[1] = (note[1] - min) * 0.5 + min note[2] = note[2] * 0.5 LC2Sysex.log_message('after: ' + str(note)) self._clip.select_all_notes() self._clip.replace_selected_notes(tuple(sel + rem))
def _compress(self, args): sel, rem = self._get_selection() min = 99999 for note in sel: if note[1] < min: min = note[1] for note in sel: LC2Sysex.log_message("before: " + str(note)) if not args[0]: note[1] = (note[1] - min) / 0.5 + min note[2] = note[2] / 0.5 else: note[1] = (note[1] - min) * 0.5 + min note[2] = note[2] * 0.5 LC2Sysex.log_message("after: " + str(note)) self._clip.select_all_notes() self._clip.replace_selected_notes(tuple(sel + rem))
def __init__(self, num_tracks, num_scenes): self._scene_count = LC2Sysex.l9() and -1 or 0 self._num_tracks = num_tracks self._height = num_scenes self._width = num_tracks self._snapshot_bank = LC2SessionBank() SessionComponent.__init__(self, num_tracks, num_scenes) LC2SceneComponent.set_get_offsets(self._get_offset) LC2ChannelStripComponent.set_get_offsets(self._get_offset) LC2ClipSlotComponent.set_get_offsets(self._get_offset) LC2ChannelStripComponent.set_playing_slot_changed(self._playing_slot_changed)
def _send_state(self): if hasattr(self, '_get_offset'): if self._get_offset is not None: offsets = self._get_offset() if self._scene_id < offsets[3]: sysex = LC2Sysex('SCENE') sysex.byte(self._scene_id) sysex.ascii(self.get_name()) sysex.rgb(self.color()) sysex.byte(self.state()) sysex.send()
def update(self): DeviceComponent.update(self) if self.is_enabled(): if self._lock_button != None: if self._locked_to_device: self._lock_button.turn_on() else: self._lock_button.turn_off() if LC2Sysex.l9(): self._update_on_off_button() else: self._on_on_off_changed()
def _flip(self, args): dir = args[0] sel, rem = self._get_selection() LC2Sysex.log_message("Fliping " + str(dir) + " " + str(sel) + " " + str(rem)) if dir: if not self._fold_notes: min = 127 max = 0 for note in sel: if note[0] > max: max = note[0] if note[0] < min: min = note[0] cs = (self._note_step(max) - self._note_step(min)) / 2.0 + self._note_step(min) LC2Sysex.log_message( str(cs) + " " + str(self._note_step(max)) + " " + str(max) + " " + str(self._note_step(min)) + " " + str(min) ) for note in sel: new_step = cs + (cs - self._note_step(note[0])) note[0] = self._note(int(new_step)) self._clip.select_all_notes() self._clip.replace_selected_notes(tuple(sel + rem)) else: min = 99999 max = -99999 for note in sel: if note[1] > max: max = note[1] if note[1] < min: min = note[1] centre = (max - min) / 2 + min for note in sel: note[1] = centre + (centre - note[1]) LC2Sysex.log_message("cent" + str(centre) + " " + str(min) + " " + str(max)) self._clip.select_all_notes() self._clip.replace_selected_notes(tuple(sel + rem))
def handle_sysex(self, sysex): if list(sysex).count(247) == 0: count = 1 else: count = list(sysex).count(247) LC2Sysex.log_message(str(sysex)) LC2Sysex.log_message('sysex count' + str(count)) msysex = [ [] for i in range(count + 1) ] id = 0 start = list(sysex).index(240) for i, b in enumerate(sysex): if i >= start: msysex[id].append(b) if b == 247: id += 1 LC2Sysex.log_message(str(msysex)) pages = [self._session, self._mixer, self._sequencer, self._modulator] for sysex in msysex: if len(sysex) > 1: if sysex[1] == 5: if sysex[2] == 1: self._init() elif sysex[2] == 2: sysex = LC2SysexParser(sysex[3:]) interface = sysex.parse('b') LC2Sysex.log_message('interface change: ' + str(interface)) if interface == 0 or interface == 1 or interface == 2: self._mixer.set_enabled(1) else: self._mixer.set_enabled(0) elif sysex[1] < len(pages): pages[sysex[1]].handle_sysex(sysex[2:])
def _launch_quant_value(self, value): if self.is_enabled(): if self._launch_quant_button is not None: LC2Sysex.log_message('valu' + str(value)) self.song().clip_trigger_quantization = Live.Song.Quantization.values[value]
def _select_device(self, sysex): tr, id = sysex.parse("bb") LC2Sysex.log_message("device select:" + str(tr) + " " + str(id)) if tr < len(self._channel_strips): self.channel_strip(tr).select_device(id)
def _bank_up(self): if LC2Sysex.l9(): SessionComponent._bank_up(self) self.send_offsets() if self.scene_offset() == 0: self._bank_up_button.turn_off()
def _select_send(self, sysex): tid, send = sysex.parse('bb') LC2Sysex.log_message(str(tid) + ' ' + str(send)) self._mixer.channel_strip(tid).select_send(send)
def _select_device(self, sysex): tr, id = sysex.parse('bb') LC2Sysex.log_message('device select:' + str(tr) + ' ' + str(id)) if tr < len(self._channel_strips): self.channel_strip(tr).select_device(id)
#Embedded file name: /Applications/Ableton Live 9 Suite.app/Contents/App-Resources/MIDI Remote Scripts/LiveControl_2_1_31/LC2ClipSlotComponent.py import Live from LC2Sysex import LC2Sysex from _Framework.ClipSlotComponent import ClipSlotComponent if LC2Sysex.l9(): from _Framework.SubjectSlot import subject_slot class LC2ClipSlotComponent(ClipSlotComponent): def set_get_offsets(func): LC2ClipSlotComponent._get_offset = func set_get_offsets = staticmethod(set_get_offsets) def release_attributes(): LC2ClipSlotComponent._get_offset = None release_attributes = staticmethod(release_attributes) def __init__(self, tid, sid): ClipSlotComponent.__init__(self) self._tid = tid self._sid = sid if not LC2Sysex.l9(): def _set_clip_slot(self, clip_slot): if clip_slot != self._clip_slot: if self._clip_slot is not None: try: self._clip_slot.remove_has_stop_button_listener(self._send_state)
def do_setup(self): if LC2Sysex.l9(): self._set_suppress_rebuild_requests(True) else: self.set_suppress_rebuild_requests(True) self._suppress_session_highlight = True self._suppress_send_midi = True LC2Sysex.set_midi_callback(self._send_midi) LC2SessionBank.set_song(self.song) LC2SessionBank.set_timer_callback(self.schedule_message) self._session = LC2SessionComponent(8, 12) self._mixer = LC2MixerComponent(8) self._session.set_mixer(self._mixer) if LC2Sysex.l9(): self.set_highlighting_session_component(self._session) bank_buttons = [ ButtonElement(False, MIDI_NOTE_TYPE, 0, 40 + i) for i in range(4) ] self._session.set_scene_bank_buttons(bank_buttons[0], bank_buttons[1]) self._session.set_track_bank_buttons(bank_buttons[2], bank_buttons[3]) mixer_controls = [ SliderElement(MIDI_CC_TYPE, 0, i) for i in range(24) ] mixer_d_controls = [ LC2ParameterElement(MIDI_CC_TYPE, 0, i + 64) for i in range(32) ] toggle_controls = [ ButtonElement(True, MIDI_NOTE_TYPE, 0, i + 1) for i in range(24) ] cf = [ ButtonElement(True, MIDI_NOTE_TYPE, 0, i + 30) for i in range(8) ] mt = [ ButtonElement(True, MIDI_NOTE_TYPE, 0, i + 50) for i in range(8) ] self._mixer.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, 0, 33)) self._mixer.master_strip().set_pan_control(SliderElement(MIDI_CC_TYPE, 0, 34)) self._mixer.set_prehear_volume_control(SliderElement(MIDI_CC_TYPE, 0, 35)) self._mixer.set_crossfader_control(SliderElement(MIDI_CC_TYPE, 0, 40)) for i in range(8): idx = i * 3 ch = self._mixer.channel_strip(i) ch.set_invert_mute_feedback(True) ch.set_mute_button(toggle_controls[idx]) ch.set_solo_button(toggle_controls[idx + 1]) ch.set_arm_button(toggle_controls[idx + 2]) ch.set_volume_control(mixer_controls[idx]) ch.set_pan_control(mixer_controls[idx + 1]) ch.set_send_control(mixer_controls[idx + 2]) ch.set_crossfade_toggle(cf[i]) ch.set_monitor_toggle(mt[i]) ch.set_device_controls(tuple(mixer_d_controls[i * 4:i * 4 + 4])) self._modulator = LC2Modulator() self.set_device_component(self._modulator) device_controls = [ LC2ParameterElement(MIDI_CC_TYPE, 1, i, True) for i in range(16) ] self._modulator.set_parameter_controls(tuple(device_controls)) device_buttons = [ ButtonElement(False, MIDI_NOTE_TYPE, 1, i) for i in range(4) ] self._modulator.set_on_off_button(device_buttons[0]) self._modulator.set_lock_button(device_buttons[1]) self._modulator.set_bank_nav_buttons(device_buttons[2], device_buttons[3]) self._sequencer = LC2Sequencer() self._session.set_sequencer(self._sequencer) self._transport = LC2TransportComponent() tbuttons = [ ButtonElement(True, MIDI_NOTE_TYPE, 0, 110 + i) for i in range(12) ] self._transport.set_stop_button(tbuttons[0]) self._transport.set_play_button(tbuttons[1]) self._transport.set_record_button(tbuttons[2]) self._transport.set_overdub_button(tbuttons[3]) self._transport.set_back_to_arranger_button(tbuttons[4]) self._transport.set_follow_button(tbuttons[5]) self._transport.set_metronome_button(tbuttons[6]) self._transport.set_tap_tempo_button(tbuttons[7]) self._transport.set_tempo_buttons(tbuttons[9], tbuttons[8]) self._transport.set_launch_quant_button(SliderElement(MIDI_CC_TYPE, 0, 120)) self._transport.set_record_quant_button(SliderElement(MIDI_CC_TYPE, 0, 121)) self._last_time = '' if LC2Sysex.l9(): def wrapper(delta): self._on_time_changed() return Task.RUNNING self._tasks.add(Task.FuncTask(wrapper, self._on_time_changed)) else: self._register_timer_callback(self._on_time_changed) self.song().add_tempo_listener(self._on_tempo_changed) for component in self.components: component.set_enabled(False) if LC2Sysex.l9(): self._set_suppress_rebuild_requests(False) else: self.set_suppress_rebuild_requests(False)