diff --git a/.gitignore b/.gitignore index 8e73498..09aded9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .mypy_cache .vscode .env +__pycache__ +src/Maschine_Mk1/.idea diff --git a/src/Maschine_Mk1/Maschine.py b/src/Maschine_Mk1/Maschine.py index 6cfa6cb..6fb29ca 100644 --- a/src/Maschine_Mk1/Maschine.py +++ b/src/Maschine_Mk1/Maschine.py @@ -72,7 +72,7 @@ def start(self): def tick(self): if not self._hold and self._wait > 0: self._wait -= 1 - if self._wait == 0 and self._func != None: + if self._wait == 0 and self._func is not None: self._func(self._grid) @@ -431,10 +431,10 @@ def update_undo_redo(self, force=False): self.redo_state = self.song().can_redo if self.song().can_undo != self.undo_state: self.undo_state = self.song().can_undo - self._undo_button.send_value(self.undo_state == 1 * 127) + self._undo_button.send_value((self.undo_state == 1) * 127) if self.song().can_redo != self.redo_state: self.redo_state = self.song().can_redo - self._redo_button.send_value(self.redo_state == 1 * 127) + self._redo_button.send_value((self.redo_state == 1) * 127) def adjust_loop_start(self, delta): loopval = self.song().loop_start @@ -577,25 +577,25 @@ def _do_toggle_send(self, value): def _a_trk_left(self, value): if value not in range(128): raise ValueError(f'value not between 0 and 127: {value}') - if value != 0 and self.application().view.is_view_visible('Session'): - direction = Live.Application.Application.View.NavDirection.left - self.application().view.scroll_view(direction, 'Session', True) - track = self.song().view.selected_track - self.timed_message(2, f'T:{track.name}', False) - if self.arm_selected_track and track.can_be_armed: - arm_exclusive(self.song(), track) + if value != 0 and self.application().view.is_view_visible('Session'): + direction = Live.Application.Application.View.NavDirection.left + self.application().view.scroll_view(direction, 'Session', True) + track = self.song().view.selected_track + self.timed_message(2, f'T:{track.name}', False) + if self.arm_selected_track and track.can_be_armed: + arm_exclusive(self.song(), track) @subject_slot('value') def _a_trk_right(self, value): if value not in range(128): raise ValueError(f'value not between 0 and 127: {value}') - if value != 0 and self.application().view.is_view_visible('Session'): - direction = Live.Application.Application.View.NavDirection.right - self.application().view.scroll_view(direction, 'Session', True) - track = self.song().view.selected_track - self.timed_message(2, f'T:{track.name}', False) - if self.arm_selected_track and track.can_be_armed: - arm_exclusive(self.song(), track) + if value != 0 and self.application().view.is_view_visible('Session'): + direction = Live.Application.Application.View.NavDirection.right + self.application().view.scroll_view(direction, 'Session', True) + track = self.song().view.selected_track + self.timed_message(2, f'T:{track.name}', False) + if self.arm_selected_track and track.can_be_armed: + arm_exclusive(self.song(), track) @subject_slot('value') def _a_sel_arm(self, value): @@ -609,8 +609,7 @@ def _a_sel_arm(self, value): @subject_slot('value') def _nav_value_left(self, value): - if not self._device_nav_button_left != None: - raise AssertionError + if self._device_nav_button_left != None: assert value in range(128) modifier_pressed = True if value != 0 and ( diff --git a/src/Maschine_Mk1/MonoNavSection.py b/src/Maschine_Mk1/MonoNavSection.py index 3ea8e7b..0d4d2f5 100644 --- a/src/Maschine_Mk1/MonoNavSection.py +++ b/src/Maschine_Mk1/MonoNavSection.py @@ -35,7 +35,7 @@ def __init__(self, mode_selector, *args, **kwargs): self._do_right_knob.subject = self.swing_knob self._do_mode_button.subject = self.mode_button self._do_alt_button.subject = self.alt_button - self._mode = MODE_ADJUST + self._set_mode(MODE_ADJUST) self._alt_down = False def do_message(self, msg, statusbarmsg=None): @@ -141,13 +141,19 @@ def _do_mode_button(self, value): elif self._alt_down: self.canonical_parent._do_focus_navigate(1) elif self._mode == MODE_ADJUST: - self._mode = MODE_NAV - self.do_message('Master Knobs control navigation') - self.mode_button.send_value(1, True) + self._set_mode(MODE_NAV) elif self._mode == MODE_NAV: - self._mode = MODE_ADJUST - self.do_message('Master Knobs control Volume | Tempo | Quantization') - self.mode_button.send_value(0, True) + self._set_mode(MODE_ADJUST) + + def _set_mode(self, value): + self._mode = value + + if self._mode == MODE_NAV: + self.do_message('Master Knobs control navigation') + self.mode_button.send_value(1, True) + elif self._mode == MODE_ADJUST: + self.do_message('Master Knobs control Volume | Tempo | Quantization') + self.mode_button.send_value(0, True) @subject_slot('value') def _do_alt_button(self, value): diff --git a/src/Maschine_Mk1/buttons/pad.py b/src/Maschine_Mk1/buttons/pad.py index 9639bb2..c6601dc 100644 --- a/src/Maschine_Mk1/buttons/pad.py +++ b/src/Maschine_Mk1/buttons/pad.py @@ -75,7 +75,7 @@ def send_value(self, value, force_send=False): self.send_c_midi(value, True) def send_color_direct(self, color): - scolor = color == None and OFF_COLOR or color + scolor = (color == None or len(color) < 4) and OFF_COLOR or color self.send_c_midi(scolor[3]) def send_c_midi(self, value, force=False): diff --git a/src/Maschine_Mk1/modes/_base.py b/src/Maschine_Mk1/modes/_base.py index 6ec256f..a9d1983 100644 --- a/src/Maschine_Mk1/modes/_base.py +++ b/src/Maschine_Mk1/modes/_base.py @@ -11,12 +11,22 @@ # from MIDI_Map import * # from PadScale import * # from MaschineSessionComponent import MaschineSessionComponent +import Live +from _Framework.Util import find_if +def find_drum_group_device(track_or_chain): + instrument = find_if(lambda d: d.type == Live.Device.DeviceType.instrument, track_or_chain.devices) + if instrument: + if instrument.can_have_drum_pads: + return instrument + if instrument.can_have_chains: + return find_if(bool, map(find_drum_group_device, instrument.chains)) def find_drum_device(track): - for device in track.devices: - if device.can_have_drum_pads: - return device + # for device in track.devices: + # if device.can_have_drum_pads: + # return device + return find_drum_group_device(track) class MaschineMode(CompoundComponent): diff --git a/src/Maschine_Mk1/modes/drum.py b/src/Maschine_Mk1/modes/drum.py index e9b292a..348876a 100644 --- a/src/Maschine_Mk1/modes/drum.py +++ b/src/Maschine_Mk1/modes/drum.py @@ -43,10 +43,11 @@ def set_button(self, button): button._pad = None def send_color(self): - if self.selected: - self._button.send_color_direct(self._color[1]) - else: - self._button.send_color_direct(self._color[0]) + if self._button is not None: + if self.selected: + self._button.send_color_direct(self._color[1]) + else: + self._button.send_color_direct(self._color[0]) def get_color(self): return self._color[1 if self.selected else 0] @@ -137,16 +138,18 @@ def _get_note_set(self): return in_notes def _update_pad_edit_color(self, pad, in_notes): - if pad._pad.note in in_notes: - pad._button.send_color_direct(pad._color[1]) - else: - pad._button.send_color_direct(pad._color[0]) + if pad._button is not None: + if pad._pad.note in in_notes: + pad._button.send_color_direct(pad._color[1]) + else: + pad._button.send_color_direct(pad._color[0]) def _update_pad_edit_mono(self, pad, in_notes): - if pad._pad.note in in_notes: - pad._button.send_value(127, True) - else: - pad._button.send_value(0, True) + if pad._button is not None: + if pad._pad.note in in_notes: + pad._button.send_value(127, True) + else: + pad._button.send_value(0, True) @subject_slot('notes') def _on_notes_changed(self): @@ -215,7 +218,8 @@ def update_pads(self): def refresh(self): if self._active: for dpad in self._pads: - dpad._button.reset() + if dpad._button is not None: + dpad._button.reset() dpad.send_color() def assign_pads(self): @@ -241,11 +245,11 @@ def assign_pads(self): dpad.set_color(((0, 0, 40), (0, 0, 40))) dpad.set_pad(None) - for button, (column, row) in self.canonical_parent._bmatrix.iterbuttons(): - pad_index = (3 - row) * 4 + column - self._pads[pad_index].set_button(button) - if not self._in_edit_mode: - self._pads[pad_index].send_color() + for button, (column, row) in self.canonical_parent._bmatrix.iterbuttons(): + pad_index = (3 - row) * 4 + column + self._pads[pad_index].set_button(button) + if not self._in_edit_mode: + self._pads[pad_index].send_color() def assign_track_device(self): if self.device and self.device.view: diff --git a/src/Maschine_Mk1/modes/pad.py b/src/Maschine_Mk1/modes/pad.py index c8bd0d9..a255344 100644 --- a/src/Maschine_Mk1/modes/pad.py +++ b/src/Maschine_Mk1/modes/pad.py @@ -212,13 +212,8 @@ def refresh(self): if button: note_index = (3 - row) * 4 + column scale_index = note_index % scale_len - octave_offset = note_index / scale_len - note_value = ( - self._scale.notevalues[scale_index] - + self._base_note - + octave * 12 - + octave_offset * 12 - ) + octave_offset = int(note_index / scale_len) + note_value = int(self._scale.notevalues[scale_index] + self._base_note + octave * 12 + octave_offset * 12) button.reset() button.send_color_direct(self.get_color_by_note_mode(note_value, False)) @@ -259,8 +254,8 @@ def assign_transpose(self, scale): if button: note_index = (3 - row) * 4 + column scale_index = note_index % scale_len - octave_offset = note_index / scale_len - note_value = scale.notevalues[scale_index] + self._base_note + octave * 12 + octave_offset * 12 + octave_offset = int(note_index / scale_len) + note_value = int(self._scale.notevalues[scale_index] + self._base_note + octave * 12 + octave_offset * 12) if note_value < 128: last_note_val = note_value elif last_note_val != None: @@ -321,9 +316,9 @@ def exit_clear_state(self): if button: note_index = (3 - row) * 4 + column scale_index = note_index % scale_len - octave_offset = note_index / scale_len + octave_offset = int(note_index / scale_len) button.send_value(0, True) - note_value = self._scale.notevalues[scale_index] + self._base_note + octave * 12 + octave_offset * 12 + note_value = int(self._scale.notevalues[scale_index] + self._base_note + octave * 12 + octave_offset * 12) button.send_color_direct(self.get_color_by_note_mode(note_value, False)) button.set_to_notemode(True) button.remove_value_listener(self._action_clear) diff --git a/src/Maschine_Mk1/modes/track.py b/src/Maschine_Mk1/modes/track.py index 8ff589c..59c79b0 100644 --- a/src/Maschine_Mk1/modes/track.py +++ b/src/Maschine_Mk1/modes/track.py @@ -85,13 +85,13 @@ def inc_offset(self, diff, nr_of_tracks): if diff < 0 and self.track_offset > 0: self.track_offset += diff return True - if diff > 0 and new_last_track < nr_of_tracks: + if diff > 0 and new_last_track <= nr_of_tracks: self.track_offset += diff return True return False def ajust_track_offest(self, nr_of_tracks): - self.track_offset = min(self.track_offset, max(0, nr_of_tracks - 16 - 1)) + self.track_offset = min(self.track_offset, max(0, nr_of_tracks - 16)) class TrackModMode(MaschineMode): @@ -111,8 +111,8 @@ def navigate(self, dir, modifier, alt_modifier=False): self._free_listeners() self._assign(False) offset = self._track_assign.track_offset + 1 - self.canonical_parent.show_message(f'Track Mode assigned to Tracks {offset} to {16 + offset}') - self.canonical_parent.timed_message(2, f'Tracks Mode to:{offset} to {16 + offset}') + self.canonical_parent.show_message(f'Track Mode assigned to Tracks {offset} to {15 + offset}') + self.canonical_parent.timed_message(2, f'Tracks Mode to:{offset} to {15 + offset}') def unbind_listener(self, track_element): pass