diff --git a/firmware/polyvec-hal/src/gw.rs b/firmware/polyvec-hal/src/gw.rs index ab00b93..68e6863 100644 --- a/firmware/polyvec-hal/src/gw.rs +++ b/firmware/polyvec-hal/src/gw.rs @@ -29,6 +29,7 @@ pub trait WavetableOscillator { pub trait PitchShift { fn set_pitch(&self, value: FixedI32); fn pitch(&self) -> FixedI32; + fn set_window_sz(&self, value: u16); } pub trait KarlsenLpf { @@ -132,6 +133,11 @@ macro_rules! pitch_shift { fn pitch(&self) -> FixedI32 { FixedI32::::from_bits(self.csr_pitch().read().bits() as i32) } + fn set_window_sz(&self, value: u16) { + unsafe { + self.csr_window_sz().write(|w| w.csr_window_sz().bits(value)); + } + } })+ }; } diff --git a/firmware/polyvec-lib/src/opt.rs b/firmware/polyvec-lib/src/opt.rs index 8ec304c..389383e 100644 --- a/firmware/polyvec-lib/src/opt.rs +++ b/firmware/polyvec-lib/src/opt.rs @@ -70,7 +70,7 @@ pub struct AdsrOptions { #[derive(Clone)] pub struct ScopeOptions { pub selected: Option, - pub delay_len: NumOption, + pub grain_sz: NumOption, pub trig_lvl: NumOption, pub trig_sns: NumOption, } @@ -110,7 +110,7 @@ impl_option_view!(AdsrOptions, attack_ms, decay_ms, release_ms, resonance); impl_option_view!(ScopeOptions, - delay_len, trig_lvl, trig_sns); + grain_sz, trig_lvl, trig_sns); impl_option_view!(TouchOptions, note_control, led_mirror); @@ -167,12 +167,12 @@ impl Options { }, scope: ScopeOptions { selected: None, - delay_len: NumOption{ - name: "delayln".into(), - value: 511, + grain_sz: NumOption{ + name: "grainsz".into(), + value: 1023, step: 1, - min: 128, - max: 511, + min: 512, + max: 1023, }, trig_lvl: NumOption{ name: "trig lvl".into(), diff --git a/firmware/polyvec/src/main.rs b/firmware/polyvec/src/main.rs index 36d7ff5..5d8cd7f 100644 --- a/firmware/polyvec/src/main.rs +++ b/firmware/polyvec/src/main.rs @@ -253,7 +253,6 @@ impl State { } } - /* if opts.touch.note_control.value == opt::NoteControl::Midi { while let Ok(event) = self.midi_in.read() { self.voice_manager.event(event, uptime_ms); @@ -261,12 +260,12 @@ impl State { self.voice_manager.tick(uptime_ms, opts); for n_voice in 0..N_VOICES { let voice = &self.voice_manager.voices[n_voice]; - shifter[n_voice].set_pitch(voice.pitch); - lpf[n_voice].set_cutoff((voice.amplitude * 8000f32) as i16); - lpf[n_voice].set_resonance(opts.adsr.resonance.value); + shifter[n_voice].set_pitch(FixedI32::::from_num(voice.pitch)); + shifter[n_voice].set_window_sz(opts.scope.grain_sz.value as u16); + lpf[n_voice].set_cutoff(FixedI32::::from_num(voice.amplitude)); + lpf[n_voice].set_resonance(FixedI32::::from_num(0)); } } else { - */ let pmod1 = &peripherals.EURORACK_PMOD1; let pmod2 = &peripherals.EURORACK_PMOD2; let pmod3 = &peripherals.EURORACK_PMOD3; @@ -302,6 +301,7 @@ impl State { let ampl = (touch_raw as f32) / 256.0f32; let pitch = note_to_pitch(midi_note); shifter[n_voice].set_pitch(FixedI32::::from_num(pitch)); + shifter[n_voice].set_window_sz(opts.scope.grain_sz.value as u16); // Low-pass filter to smooth touch on/off let ampl_old: f32 = lpf[n_voice].cutoff().to_num(); @@ -351,9 +351,7 @@ impl State { update_hw_voice(n_voice, voices_old[n_voice].note, 0); } } - /* } - */ self.last_control_type = Some(opts.touch.note_control.value); } diff --git a/rtl/dsp.py b/rtl/dsp.py index ea9c85f..0a210eb 100644 --- a/rtl/dsp.py +++ b/rtl/dsp.py @@ -447,7 +447,7 @@ def __init__(self, n_lpfs=2): class LpfDecorator(Module, AutoCSR): def __init__(self, lpf, dw=32): - self.csr_g = CSRStorage(dw, reset=Constant(float_to_fp(1.0), (32, True))) + self.csr_g = CSRStorage(dw, reset=Constant(float_to_fp(0.0), (32, True))) self.csr_resonance = CSRStorage(dw, reset=Constant(float_to_fp(0.0), (32, True))) self.comb += [ lpf.g.eq(self.csr_g.storage),