tangled
alpha
login
or
join now
ericwood.org
/
macropad-sequencer
1
fork
atom
A step sequencer for Adafruit's RP2040-based macropad
1
fork
atom
overview
issues
pulls
pipelines
remove swing, add step count
ericwood.org
2 months ago
c5a7e77b
f802729c
+27
-23
5 changed files
expand all
collapse all
unified
split
src
menus
sequencer.rs
sequencer_timer.rs
tasks
controls.rs
display.rs
sequencer.rs
+8
-8
src/menus/sequencer.rs
···
23
23
pub play: bool,
24
24
pub bpm: u32,
25
25
pub timing: TimingOption,
26
26
-
pub swing: u32,
26
26
+
pub steps: u32,
27
27
}
28
28
29
29
impl Default for SequencerMenuValue {
···
32
32
play: false,
33
33
bpm: 120,
34
34
timing: TimingOption::Eighth,
35
35
-
swing: 0,
35
35
+
steps: 12,
36
36
}
37
37
}
38
38
}
···
44
44
pub play_menu: BooleanMenuItem<'a, SequencerMenuValue>,
45
45
pub bpm_menu: NumericMenuItem<'a, SequencerMenuValue>,
46
46
pub timing_menu: EnumMenuItem<'a, SequencerMenuValue, 6, TimingOption>,
47
47
-
pub swing_menu: NumericMenuItem<'a, SequencerMenuValue>,
47
47
+
pub steps_menu: NumericMenuItem<'a, SequencerMenuValue>,
48
48
}
49
49
50
50
impl<'a> SequencerMenuItems<'a> {
···
83
83
menu_value.timing = value;
84
84
},
85
85
);
86
86
-
let swing_menu = NumericMenuItem::<SequencerMenuValue>::new(
87
87
-
"SWING",
88
88
-
defaults.swing,
86
86
+
let steps_menu = NumericMenuItem::<SequencerMenuValue>::new(
87
87
+
"STEPS",
88
88
+
defaults.steps,
89
89
&|menu_value, value| {
90
90
-
menu_value.swing = value;
90
90
+
menu_value.steps = value;
91
91
},
92
92
);
93
93
···
101
101
play_menu,
102
102
bpm_menu,
103
103
timing_menu,
104
104
-
swing_menu,
104
104
+
steps_menu,
105
105
}
106
106
}
107
107
}
-6
src/sequencer_timer.rs
···
1
1
use embassy_time::Timer;
2
2
3
3
-
use crate::{COLS, ROWS};
4
4
-
5
3
#[derive(Clone, Copy, Default, PartialEq)]
6
4
pub enum TimingOption {
7
5
#[default]
···
13
11
SixteenthTriplet,
14
12
}
15
13
16
16
-
const NUM_STEPS: usize = ROWS * COLS;
17
17
-
18
14
pub struct SequencerConfig {
19
15
pub bpm: u32,
20
16
pub timing: TimingOption,
21
21
-
pub swing: u32,
22
17
}
23
18
24
19
pub struct SequencerTimer {
···
31
26
let config = SequencerConfig {
32
27
bpm: 120,
33
28
timing: TimingOption::Quarter,
34
34
-
swing: 0,
35
29
};
36
30
37
31
let speed_ms = config_to_ms(&config);
+16
-6
src/tasks/controls.rs
···
37
37
let off = RGB { r: 0, g: 0, b: 0 };
38
38
let current = RGB { r: 32, g: 0, b: 0 };
39
39
40
40
+
let mut num_steps = 12;
40
41
let mut num_keys_pressed = 0;
41
42
let mut selected_step: Option<Coord> = None;
42
43
let mut step_index: usize = 0;
···
86
87
off
87
88
};
88
89
89
89
-
step_index = (step_index + 1).rem_euclid(NUM_KEYS);
90
90
-
let mut next_step = ((step_index % COLS) as u8, (step_index / COLS) as u8);
91
91
-
if num_keys_pressed > 0 {
92
92
-
while !step_state[next_step.1 as usize][next_step.0 as usize].pressed {
90
90
+
let next_step = if num_keys_pressed > 0 {
91
91
+
step_index = (step_index + 1).rem_euclid(NUM_KEYS);
92
92
+
let mut next = coord_from_index(step_index);
93
93
+
while !step_state[next.1 as usize][next.0 as usize].pressed {
93
94
step_index = (step_index + 1).rem_euclid(NUM_KEYS);
94
94
-
next_step = ((step_index % COLS) as u8, (step_index / COLS) as u8);
95
95
+
next = coord_from_index(step_index)
95
96
}
96
96
-
}
97
97
+
next
98
98
+
} else {
99
99
+
step_index = (step_index + 1).rem_euclid(num_steps);
100
100
+
coord_from_index(step_index)
101
101
+
};
97
102
98
103
update_key_light(step, prev_color).await;
99
104
update_key_light(next_step, current).await;
100
105
step = next_step;
101
106
}
102
107
ControlEvent::SequencerMenuChange { value } => unsafe {
108
108
+
num_steps = value.steps as usize;
103
109
SEQUENCER_MENU.lock_mut(|inner| *inner = Some(value));
104
110
},
105
111
ControlEvent::StepMenuChange { value } => {
···
109
115
}
110
116
}
111
117
}
118
118
+
}
119
119
+
120
120
+
fn coord_from_index(index: usize) -> Coord {
121
121
+
((index % COLS) as u8, (index / COLS) as u8)
112
122
}
113
123
114
124
async fn set_step_menu(value: Option<StepMenuValue>) {
+1
-1
src/tasks/display.rs
···
26
26
&mut sequencer_items.play_menu,
27
27
&mut sequencer_items.bpm_menu,
28
28
&mut sequencer_items.timing_menu,
29
29
-
&mut sequencer_items.swing_menu,
29
29
+
&mut sequencer_items.steps_menu,
30
30
],
31
31
&|value| {
32
32
let _ = CONTROLS_CHANNEL.try_send(ControlEvent::SequencerMenuChange { value: *value });
+2
-2
src/tasks/sequencer.rs
···
14
14
play: temp_play,
15
15
bpm,
16
16
timing,
17
17
-
swing,
17
17
+
steps: _steps,
18
18
} = value.unwrap();
19
19
-
timer.set(SequencerConfig { bpm, timing, swing });
19
19
+
timer.set(SequencerConfig { bpm, timing });
20
20
play = temp_play;
21
21
});
22
22