diff --git a/crates/velociter/src/lib.rs b/crates/velociter/src/lib.rs index 6d63f2f..ae3c6e8 100644 --- a/crates/velociter/src/lib.rs +++ b/crates/velociter/src/lib.rs @@ -13,6 +13,9 @@ baseplug::model! { #[model(min = 0.0, max = 127.9)] #[parameter(name = "max_vel")] max_vel: f32, + #[model(min = 0.0, max = 10.)] + #[parameter(name = "repetition")] + repetition: f32, } } @@ -21,12 +24,15 @@ impl Default for VelociterModel { Self { min_vel: 0.0, max_vel: 127.9, + repetition: 0.0, } } } struct Velociter { notes: Vec<[u8; 3]>, + last_val: u8, + counter: u8, } impl Plugin for Velociter { @@ -43,6 +49,8 @@ impl Plugin for Velociter { fn new(_sample_rate: f32, _model: &VelociterModel) -> Self { Self { notes: Vec::with_capacity(300), + last_val: 0, + counter: u8::MAX, } } @@ -55,23 +63,32 @@ impl Plugin for Velociter { use rand::{thread_rng, Rng}; let mut rng = thread_rng(); + let min = model.min_vel[0]; + let max = model.max_vel[0]; + // make sure they're right + let (min, max) = (min.min(max), max.max(min)); + + for mut note in self.notes.drain(0..) { + let val = if model.repetition[0] < self.counter as f32 { + self.counter = 0; + rng.gen_range(min..max).trunc() as u8 + } else { + self.counter += 1; + self.last_val + }; + self.last_val = val; + + note[2] = val; + let note = Event:: { + frame: 0, + data: Data::Midi(note), + }; + enqueue_midi(note); + } + for i in 0..ctx.nframes { output[0][i] = input[0][i]; output[1][i] = input[1][i]; - - let min = model.min_vel[i]; - let max = model.max_vel[i]; - // make sure they're right - let (min, max) = (min.min(max), max.max(min)); - - for mut note in self.notes.drain(0..) { - note[2] = rng.gen_range(min..max).trunc() as u8; - let note = Event:: { - frame: 0, - data: Data::Midi(note), - }; - enqueue_midi(note); - } } } } @@ -81,4 +98,4 @@ impl MidiReceiver for Velociter { } } -baseplug::vst2!(Velociter, b"tAnE"); +baseplug::vst2!(Velociter, b"iter");