Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 30 additions & 6 deletions QControlComponent.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,10 @@ def __init__(self, parent):
self._update_lights()

def _set_color(self, buttonid, color):


colordict = dict(black=0, red=1, blue=16, magenta=17)

self._parent._send_midi(
self._parent.QS.set_B_color(buttonid, colordict[color]))

Expand Down Expand Up @@ -1254,9 +1257,13 @@ def callback():
def _duplicate_loop(self):
clip_slot = self._parent.song().view.highlighted_clip_slot
if clip_slot == None:
self._parent.show_message(symb_stop + " no loop to duplicate")
return
if not clip_slot.has_clip:
self._parent.show_message(symb_stop + " no loop to duplicate")
return
if clip_slot.has_clip:
clip_slot.clip.duplicate_loop()

clip_slot.clip.duplicate_loop()

def _duplicate_or_delete_track(self):
if self.__control_layer_permanent and self._shift_pressed:
Expand Down Expand Up @@ -1334,9 +1341,15 @@ def _delete_scene(self):

def _delete_clip(self):
clip_slot = self._parent.song().view.highlighted_clip_slot
if clip_slot != None:
if clip_slot.has_clip:
clip_slot.delete_clip()
if clip_slot == None:
self._parent.show_message(symb_stop + " no clip to delete")
return
if not clip_slot.has_clip:
self._parent.show_message(symb_stop + " no clip to delete")
return

clip_slot.delete_clip()


def _delete_device(self):
track = self._parent.song().view.selected_track
Expand Down Expand Up @@ -1404,6 +1417,13 @@ def _stop_clip_or_allclips(self):
def _duplicate_clip(self):
# duplicate the clip slot
if self.selected_track == None:
self._parent.show_message(symb_stop + " no clip to duplicate")
return
if not self.selected_clip_slot.has_clip:
self._parent.show_message(symb_stop + " no clip to duplicate")
return
if self.selected_clip_slot.is_recording:
self._parent.show_message(symb_stop + " A clip cannot be copied while it is recording.")
return

duplicated_id = self.selected_track.duplicate_clip_slot(
Expand Down Expand Up @@ -1756,7 +1776,11 @@ def _transpose(self, value, set_values=True):
)
if set_values:
self._set_notes(self._transpose_val)
self._parent.show_message(get_midi_note_name(self._transpose_val))

if not self._sequencer:
self._parent.show_message(get_midi_note_name(self._transpose_val))
else:
self.QSequencer.show_sequence_info(keepalive=False)

# ---------------
# indicate the transposed note via button lights
Expand Down
49 changes: 36 additions & 13 deletions QSequencer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Live
from .QSetup import QSetup
import time
from itertools import groupby

# fmt: off
symb_voltage = u"\u26A1"
Expand Down Expand Up @@ -47,6 +48,13 @@ def simplify_fraction(numer, denom):
return f"{reduced_num:.0f}/{reduced_den:.0f}"


def get_midi_note_name(value):
octave = int(value / 12) - 2
note = "C C#D D#E F F#G G#A A#B "[(value % 12) * 2: (value % 12) * 2 + 2]
return (note.strip() + str(octave)).ljust(3)

fullnotes = [i for i in range(128) if "#" not in get_midi_note_name(i)]

# class QSequencer(ControlSurface):
class QSequencer(object):
def __init__(self, parent):
Expand Down Expand Up @@ -712,12 +720,13 @@ def get_all_note_specs(self, note):

# -------------------------------------------

def show_sequence_info(self):
def show_sequence_info(self, keepalive=True):
# keep message alive until a clip is created
if self.clip is None:
self._parent._parent.schedule_message(16, self.show_sequence_info)
else:
self._parent._parent._task_group.clear()
if keepalive:
if self.clip is None:
self._parent._parent.schedule_message(16, self.show_sequence_info)
else:
self._parent._parent._task_group.clear()

n_velocity = self.note_velocities.index(self.note_velocity)
v_symb = v_bars[n_velocity]
Expand All @@ -731,13 +740,23 @@ def show_sequence_info(self):

pitchmsg = f"(pitch {self.sequence_up} every {self.sequence_n} notes)"



sequence = self.set_sequence()

seqmsg = f" {symb_blue_diamond_small} ".join([" ".join(i[1]) for i in groupby(map(get_midi_note_name, sequence))])
seqmsg = f"{symb_blue_diamond_small} {seqmsg} {symb_blue_diamond_small}"


self._parent._parent.show_message(
" " * 15
+ msg
+ " " * 15
+ f"{simplify_fraction(self.sequence_length, self.n_notes * 4)} BARS "
+ " " * 15
+ pitchmsg
+ " " * 15
+ seqmsg
)

def set_sequence_length_button(self, i):
Expand Down Expand Up @@ -839,16 +858,20 @@ def init_sequence(self):
self.add_handler()

def set_sequence(self):
notes = [self._parent._transpose_val for i in range(16)]
basenote = self._parent._transpose_val
if "#" in get_midi_note_name(basenote):
basenote += 1

pos = fullnotes.index(basenote)

notes = [basenote for i in range(16)]
if self.sequence_n > 0:
for i in range(0, 16, self.sequence_n):
for j in range(self.sequence_n):
if i + j < len(notes):
notes[i + j] = (
notes[i + j] + i // self.sequence_n *
self.sequence_up
)
for n, i in enumerate(range(0, 16, self.sequence_n)):
for j in range(i, i + self.sequence_n):
if j == 16: break
note = fullnotes[pos + n * self.sequence_up]
notes[j] = note

return notes

# get_notes_extended( (int)from_pitch, (int)pitch_span, (float)from_time, (float)time_span) ->
Expand Down
5 changes: 3 additions & 2 deletions QSetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,9 @@ def __init__(self):
funcs = self._get_callbacks(c)
setattr(self, "set_B_" + key, funcs[0])
setattr(self, "get_B_" + key, funcs[1])
setattr(self, "set_E_" + key, funcs[2])
setattr(self, "get_E_" + key, funcs[3])
if key != "color":
setattr(self, "set_E_" + key, funcs[2])
setattr(self, "get_E_" + key, funcs[3])

E_acc_set, E_acc_get = self._get_acceleration_callback()
setattr(self, "set_E_acceleration", E_acc_set)
Expand Down