midi_controller/
encoder_accel.rs1#[derive(Debug, Clone)]
8pub struct EncoderAccel {
9 last_detent_ms: u32,
10 initialized: bool,
11}
12
13impl Default for EncoderAccel {
14 fn default() -> Self {
15 Self::new()
16 }
17}
18
19impl EncoderAccel {
20 pub fn new() -> Self {
21 Self {
22 last_detent_ms: 0,
23 initialized: false,
24 }
25 }
26
27 pub fn steps(&mut self, now_ms: u32) -> u8 {
30 if !self.initialized {
31 self.last_detent_ms = now_ms;
32 self.initialized = true;
33 return 1;
34 }
35
36 let interval_ms = now_ms.wrapping_sub(self.last_detent_ms);
37 self.last_detent_ms = now_ms;
38
39 accel_curve(interval_ms)
40 }
41
42 pub fn reset(&mut self) {
44 self.initialized = false;
45 }
46}
47
48fn accel_curve(interval_ms: u32) -> u8 {
51 if interval_ms < 20 {
52 8 } else if interval_ms < 50 {
54 4 } else if interval_ms < 100 {
56 2 } else {
58 1 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn first_detent_always_one_step() {
68 let mut enc = EncoderAccel::new();
69 assert_eq!(enc.steps(1000), 1);
70 }
71
72 #[test]
73 fn slow_turn_gives_one_step() {
74 let mut enc = EncoderAccel::new();
75 enc.steps(0);
76 assert_eq!(enc.steps(200), 1);
77 assert_eq!(enc.steps(500), 1);
78 }
79
80 #[test]
81 fn moderate_turn_gives_two_steps() {
82 let mut enc = EncoderAccel::new();
83 enc.steps(0);
84 assert_eq!(enc.steps(80), 2);
85 assert_eq!(enc.steps(150), 2); }
87
88 #[test]
89 fn fast_turn_gives_four_steps() {
90 let mut enc = EncoderAccel::new();
91 enc.steps(0);
92 assert_eq!(enc.steps(30), 4);
93 }
94
95 #[test]
96 fn very_fast_turn_gives_eight_steps() {
97 let mut enc = EncoderAccel::new();
98 enc.steps(0);
99 assert_eq!(enc.steps(10), 8);
100 assert_eq!(enc.steps(15), 8); }
102
103 #[test]
104 fn reset_makes_next_return_one() {
105 let mut enc = EncoderAccel::new();
106 enc.steps(0);
107 enc.steps(10); enc.reset();
109 assert_eq!(enc.steps(20), 1); }
111
112 #[test]
113 fn acceleration_slows_down() {
114 let mut enc = EncoderAccel::new();
115 enc.steps(0);
116 assert_eq!(enc.steps(10), 8); assert_eq!(enc.steps(110), 1); }
119
120 #[test]
121 fn wrapping_timestamp() {
122 let mut enc = EncoderAccel::new();
123 enc.steps(u32::MAX - 10);
124 assert_eq!(enc.steps(9), 4); }
129}