use crate::prelude::*; use super::*; pub fn handle (s: &mut Sequencer, event: &AppEvent) -> Usually { handle_keymap(s, event, KEYMAP) } pub const KEYMAP: &'static [KeyBinding] = keymap!(Sequencer { [Up, NONE, "cursor_up", "move cursor up", cursor_up], [Down, NONE, "cursor_down", "move cursor down", cursor_down], [Left, NONE, "cursor_left", "move cursor left", cursor_left], [Right, NONE, "cursor_right", "move cursor right", cursor_right], [Char(']'), NONE, "cursor_inc", "increase note duration", cursor_duration_inc], [Char('['), NONE, "cursor_dec", "decrease note duration", cursor_duration_dec], [Char('`'), NONE, "mode_next", "Next view mode", mode_next], [Char('+'), NONE, "zoom_in", "Zoom in", nop], [Char('-'), NONE, "zoom_out", "Zoom out", nop], [Char('a'), NONE, "note_add", "Add note", note_add], [Char('z'), NONE, "note_del", "Delete note", note_del], [CapsLock, NONE, "advance", "Toggle auto advance", nop], [Char('w'), NONE, "rest", "Advance by note duration", nop], [Char(' '), NONE, "toggle_play", "Toggle play/pause", toggle_play], [Char('r'), NONE, "toggle_record", "Toggle recording", toggle_record], [Char('d'), NONE, "toggle_overdub", "Toggle overdub", toggle_overdub], [Char('m'), NONE, "toggle_monitor", "Toggle input monitoring", toggle_monitor], [Char('s'), NONE, "stop_and_rewind", "Stop and rewind", stop_and_rewind], [Char('q'), NONE, "quantize_next", "Next quantize value", quantize_next], [Char('Q'), SHIFT, "quantize_prev", "Previous quantize value", quantize_prev], [Char('n'), NONE, "note_axis", "Focus note axis", nop], [Char('t'), NONE, "time_axis", "Focus time axis", nop], [Char('v'), NONE, "variations", "Focus variation selector", nop], [Char('s'), SHIFT, "sync", "Focus sync selector", nop], [Char('1'), NONE, "seq_1", "Phrase 1", focus_seq(0)], [Char('2'), NONE, "seq_2", "Phrase 2", focus_seq(1)], [Char('3'), NONE, "seq_3", "Phrase 3", focus_seq(2)], [Char('4'), NONE, "seq_4", "Phrase 4", focus_seq(3)], [Char('5'), NONE, "seq_5", "Phrase 5", focus_seq(4)], [Char('6'), NONE, "seq_6", "Phrase 6", focus_seq(5)], [Char('7'), NONE, "seq_7", "Phrase 7", focus_seq(6)], [Char('8'), NONE, "seq_8", "Phrase 8", focus_seq(7)], }); const fn focus_seq (i: usize) -> impl Fn(&mut Sequencer)->Usually { move |s: &mut Sequencer| { s.sequence = i; Ok(true) } } fn nop (_: &mut Sequencer) -> Usually { Ok(false) } fn note_add (s: &mut Sequencer) -> Usually { let step = (s.time_axis.0 + s.time_cursor) as u32; let start = (step as usize * s.timebase.ppq() / s.resolution) as u32; let end = ((step + 1) as usize * s.timebase.ppq() / s.resolution) as u32; let key = u7::from_int_lossy((s.note_cursor + s.note_axis.0) as u8); let note_on = MidiMessage::NoteOn { key, vel: 100.into() }; let note_off = MidiMessage::NoteOff { key, vel: 100.into() }; let sequence = &mut s.phrases[s.sequence].notes; if sequence.contains_key(&start) { sequence.get_mut(&start).unwrap().push(note_on.clone()); } else { sequence.insert(start, vec![note_on]); } if sequence.contains_key(&end) { sequence.get_mut(&end).unwrap().push(note_off.clone()); } else { sequence.insert(end, vec![note_off]); }; Ok(true) } fn note_del (_: &mut Sequencer) -> Usually { Ok(true) } fn time_cursor_inc (s: &mut Sequencer) -> Usually { let time = s.time_axis.1 - s.time_axis.0; s.time_cursor = ((time + s.time_cursor) + 1) % time; Ok(true) } fn time_cursor_dec (s: &mut Sequencer) -> Usually { let time = s.time_axis.1 - s.time_axis.0; s.time_cursor = ((time + s.time_cursor) - 1) % time; Ok(true) } fn note_cursor_inc (s: &mut Sequencer) -> Usually { let note = s.note_axis.1 - s.note_axis.0; s.note_cursor = ((note + s.note_cursor) + 1) % note; Ok(true) } fn note_cursor_dec (s: &mut Sequencer) -> Usually { let note = s.note_axis.1 - s.note_axis.0; s.note_cursor = ((note + s.note_cursor) - 1) % note; Ok(true) } fn cursor_up (s: &mut Sequencer) -> Usually { match s.mode { SequencerView::Vertical => time_cursor_dec(s), SequencerView::Horizontal => note_cursor_dec(s), _ => Ok(false) }?; Ok(true) } fn cursor_down (s: &mut Sequencer) -> Usually { match s.mode { SequencerView::Vertical => time_cursor_inc(s), SequencerView::Horizontal => note_cursor_inc(s), _ => Ok(false) }?; Ok(true) } fn cursor_left (s: &mut Sequencer) -> Usually { match s.mode { SequencerView::Vertical => note_cursor_dec(s), SequencerView::Horizontal => time_cursor_dec(s), _ => Ok(false) }?; Ok(true) } fn cursor_right (s: &mut Sequencer) -> Usually { match s.mode { SequencerView::Vertical => note_cursor_inc(s), SequencerView::Horizontal => time_cursor_inc(s), _ => Ok(false) }?; Ok(true) } fn cursor_duration_inc (_: &mut Sequencer) -> Usually { //s.cursor.2 = s.cursor.2 + 1 Ok(true) } fn cursor_duration_dec (_: &mut Sequencer) -> Usually { //if s.cursor.2 > 0 { s.cursor.2 = s.cursor.2 - 1 } Ok(true) } fn mode_next (s: &mut Sequencer) -> Usually { s.mode = s.mode.next(); Ok(true) } impl SequencerView { fn next (&self) -> Self { match self { Self::Horizontal => Self::Vertical, Self::Vertical => Self::Tiny, Self::Tiny => Self::Horizontal, _ => self.clone() } } } fn stop_and_rewind (s: &mut Sequencer) -> Usually { s.transport.stop()?; s.transport.locate(0)?; s.playing = TransportState::Stopped; Ok(true) } fn toggle_play (s: &mut Sequencer) -> Usually { s.playing = match s.playing { TransportState::Stopped => { s.transport.start()?; TransportState::Starting }, _ => { s.transport.stop()?; s.transport.locate(0)?; TransportState::Stopped }, }; Ok(true) } fn toggle_record (s: &mut Sequencer) -> Usually { s.recording = !s.recording; Ok(true) } fn toggle_overdub (s: &mut Sequencer) -> Usually { s.overdub = !s.overdub; Ok(true) } fn toggle_monitor (s: &mut Sequencer) -> Usually { s.monitoring = !s.monitoring; Ok(true) } fn quantize_next (s: &mut Sequencer) -> Usually { if s.resolution < 64 { s.resolution = s.resolution * 2; } Ok(true) } fn quantize_prev (s: &mut Sequencer) -> Usually { if s.resolution > 1 { s.resolution = s.resolution / 2; } Ok(true) }