diff --git a/src/dsp/helpers.rs b/src/dsp/helpers.rs index 0425e6b..d4b62e8 100644 --- a/src/dsp/helpers.rs +++ b/src/dsp/helpers.rs @@ -2138,7 +2138,7 @@ impl TriSawLFO { pub struct Quantizer { old_mask: i64, keys: [f32; 12], - lkup_tbl: [u8; 24], + lkup_tbl: [(i8, i8); 24], } impl Quantizer { @@ -2146,7 +2146,7 @@ impl Quantizer { Self { old_mask: 0xFFFF_FFFF, keys: [0.0; 12], - lkup_tbl: [0; 24] + lkup_tbl: [(0, 0); 24] } } @@ -2216,16 +2216,30 @@ impl Quantizer { continue; } + println!("I={:3} NOTE={:3} (IDX={:3} => bitset {}) DIST={:3}", + i, note, note_idx, + if (mask & (0x1 << ((note_idx + 9) % 12))) > 0x0 { 1 } else { 0 }, + dist); + if dist < min_dist { - min_d_note_idx = note_idx; +// min_d_note_idx = note_idx; + min_d_note_idx = note; min_dist = dist; } else { break; } } - self.lkup_tbl[i as usize] = min_d_note_idx as u8; + self.lkup_tbl[i as usize] = ( + if min_d_note_idx < 0 { -1 } + else if min_d_note_idx > 11 { 1 } + else { 0 }, + min_d_note_idx.rem_euclid(12) as i8 + ); } + + println!("KEYS: {:?}", self.keys); + println!("TBL: {:?}", self.lkup_tbl); } //# float pitch = inputs[PITCH_INPUT].getVoltage(c); @@ -2244,15 +2258,17 @@ impl Quantizer { let octave = note_num.div_euclid(24); let note_idx = note_num - octave * 24; - println!( - "INP {:7.4} => octave={:3}, note_idx={:3} note_num={:3} inp={:9.6}", - inp, octave, note_idx, note_num, inp * 240.0); +// println!( +// "INP {:7.4} => octave={:3}, note_idx={:3} note_num={:3} inp={:9.6}", +// inp, octave, note_idx, note_num, inp * 240.0); //d// println!("KEYS: {:?}", self.keys); + //d// println!("TBL: {:?}", self.lkup_tbl); - let note_idx = self.lkup_tbl[note_idx as usize % 24]; - let pitch = self.keys[note_idx as usize]; + let (oct_offs, note_idx) = + self.lkup_tbl[note_idx as usize % 24]; + let pitch = self.keys[note_idx as usize]; - pitch + octave as f32 * 0.1 + pitch + (oct_offs as i64 + octave) as f32 * 0.1 } } diff --git a/tests/quant.rs b/tests/quant.rs index 1366ff4..aff8033 100644 --- a/tests/quant.rs +++ b/tests/quant.rs @@ -9,7 +9,7 @@ use hexodsp::dsp::helpers::Quantizer; use hexodsp::d_pit; #[test] -fn check_quant_1() { +fn check_quant_pos_neg_exact() { let mut q = Quantizer::new(); q.set_keys(0x0); @@ -57,3 +57,91 @@ fn check_quant_1() { 220.0 ]); } + +#[test] +fn check_quant_precise_01_range() { + let mut q = Quantizer::new(); + q.set_keys(0x0); + + let v = + (0..=48).map(|i| + d_pit!( + q.process( + i as f32 * ((0.1 * 0.25) / 12.0))) + ).collect::>(); + + assert_vec_feq!(v, vec![ + 440.0, + 466.1638, 466.1638, 466.1638, 466.1638, + 493.8833, 493.8833, 493.8833, 493.8833, + 523.2511, 523.2511, 523.2511, 523.2511, + 554.3653, 554.3653, 554.3653, 554.3653, + 587.3295, 587.3295, 587.3295, 587.3295, + 622.25397, 622.25397, 622.25397, 622.25397, + 659.2551, 659.2551, 659.2551, 659.2551, + 698.4565, 698.4565, 698.4565, 698.4565, + 739.98883, 739.98883, 739.98883, 739.98883, + 783.9909, 783.9909, 783.9909, 783.9909, + 830.6094, 830.6094, 830.6094, 830.6094, + 880.0, 880.0, 880.0, 880.0 + ]); +} + +#[test] +fn check_quant_neg_pos_range() { + let mut q = Quantizer::new(); + q.set_keys(0x0); + + let v = + (0..=48).map(|i| { + let i = i - 24; + d_pit!( + q.process( + i as f32 * ((0.1 * 0.25) / 12.0))) + }).collect::>(); + + assert_vec_feq!(v, vec![ + 311.12698, 311.12698, + 329.62756, 329.62756, 329.62756, 329.62756, + 349.22824, 349.22824, 349.22824, 349.22824, + 369.99442, 369.99442, 369.99442, 369.99442, + 391.99542, 391.99542, 391.99542, 391.99542, + 415.3047, 415.3047, 415.3047, 415.3047, + 440.0, 440.0, 440.0, + 466.1638, 466.1638, 466.1638, 466.1638, + 493.8833, 493.8833, 493.8833, 493.8833, + 523.2511, 523.2511, 523.2511, 523.2511, + 554.3653, 554.3653, 554.3653, 554.3653, + 587.3295, 587.3295, 587.3295, 587.3295, + 622.25397, 622.25397, 622.25397, 622.25397 + ]); +} + +#[test] +fn check_quant_edge_oct_offs() { + let mut q = Quantizer::new(); + q.set_keys(0b1001_0000_0000); + + let v = + (0..=24).map(|i| { + d_pit!( + q.process( + i as f32 * ((0.1 * 0.5) / 12.0))) + }).collect::>(); + + assert_vec_feq!(v, vec![ + 311.12698, 311.12698, + 329.62756, 329.62756, 329.62756, 329.62756, + 349.22824, 349.22824, 349.22824, 349.22824, + 369.99442, 369.99442, 369.99442, 369.99442, + 391.99542, 391.99542, 391.99542, 391.99542, + 415.3047, 415.3047, 415.3047, 415.3047, + 440.0, 440.0, 440.0, + 466.1638, 466.1638, 466.1638, 466.1638, + 493.8833, 493.8833, 493.8833, 493.8833, + 523.2511, 523.2511, 523.2511, 523.2511, + 554.3653, 554.3653, 554.3653, 554.3653, + 587.3295, 587.3295, 587.3295, 587.3295, + 622.25397, 622.25397, 622.25397, 622.25397 + ]); +}