#![allow(incomplete_features)] #![feature(generic_associated_types)] use baseplug::{event::Data, Event, MidiReceiver, Plugin, ProcessContext}; use serde::{Deserialize, Serialize}; baseplug::model! { #[derive(Debug, Serialize, Deserialize)] struct VelociterModel { #[model(min = 0.0, max = 127.9)] #[parameter(name = "min_vel")] min_vel: f32, #[model(min = 0.0, max = 127.9)] #[parameter(name = "max_vel")] max_vel: f32, } } impl Default for VelociterModel { fn default() -> Self { Self { min_vel: 0.0, max_vel: 127.9, } } } struct Velociter { notes: Vec<[u8; 3]>, } impl Plugin for Velociter { const NAME: &'static str = "velociter"; const PRODUCT: &'static str = "velociter"; const VENDOR: &'static str = "unnieversal"; const INPUT_CHANNELS: usize = 2; const OUTPUT_CHANNELS: usize = 2; type Model = VelociterModel; #[inline] fn new(_sample_rate: f32, _model: &VelociterModel) -> Self { Self { notes: Vec::with_capacity(300), } } #[inline] fn process(&mut self, model: &VelociterModelProcess, ctx: &mut ProcessContext) { let input = &ctx.inputs[0].buffers; let output = &mut ctx.outputs[0].buffers; let enqueue_midi = &mut ctx.enqueue_event; use rand::{thread_rng, Rng}; let mut rng = thread_rng(); 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); } } } } impl MidiReceiver for Velociter { fn midi_input(&mut self, _model: &VelociterModelProcess, data: [u8; 3]) { self.notes.push(data); } } baseplug::vst2!(Velociter, b"tAnE");