From 46901bf5c9dda69fba0b75c949442533fc0fad51 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Tue, 8 Mar 2022 21:10:36 +0100 Subject: [PATCH] Add a basic version of Crisp --- plugins/crisp/src/lib.rs | 22 +++++++++++++--------- plugins/crisp/src/pcg.rs | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/plugins/crisp/src/lib.rs b/plugins/crisp/src/lib.rs index 6e11068a..30dfee7e 100644 --- a/plugins/crisp/src/lib.rs +++ b/plugins/crisp/src/lib.rs @@ -15,6 +15,7 @@ // along with this program. If not, see . use nih_plug::prelude::*; +use pcg::Pcg32iState; use std::pin::Pin; mod pcg; @@ -23,7 +24,7 @@ mod pcg; const NUM_CHANNELS: usize = 2; /// These seeds being fixed makes bouncing deterministic. -const INITIAL_PRNG_SEEDS: [u32; 2] = [69, 420]; +const INITIAL_PRNG_SEED: Pcg32iState = Pcg32iState::new(69, 420); /// This plugin essentially layers the sound with another copy of the signal AM'ed with white (or /// filtered) noise. That other copy of the sound may have a low pass filter applied to it since @@ -31,9 +32,9 @@ const INITIAL_PRNG_SEEDS: [u32; 2] = [69, 420]; struct Crisp { params: Pin>, - /// The OS RNG is only used for the initial seeds, after that we'll implement PCG ourselves so - /// we can easily SIMD-ify this in the future. - prng_seeds: [u32; NUM_CHANNELS], + /// A PRNG for generating noise, after that we'll implement PCG ourselves so we can easily + /// SIMD-ify this in the future. + prng: Pcg32iState, } // TODO: Filters @@ -51,7 +52,7 @@ impl Default for Crisp { Self { params: Box::pin(CrispParams::default()), - prng_seeds: INITIAL_PRNG_SEEDS, + prng: INITIAL_PRNG_SEED, } } } @@ -91,7 +92,7 @@ impl Plugin for Crisp { fn reset(&mut self) { // By using the same seeds each time bouncing can be made deterministic - self.prng_seeds = INITIAL_PRNG_SEEDS; + self.prng = INITIAL_PRNG_SEED; } fn process( @@ -103,9 +104,12 @@ impl Plugin for Crisp { let amount = self.params.amount.smoothed.next(); // TODO: SIMD-ize this to process both channels at once - for (channel_idx, sample) in channel_samples.into_iter().enumerate() { - // TODO: Calculate some uniformly (or Gaussian?) distributed white noise in the - // range of `[-1, 1]`, add that scaled by `amount` to `sample`. + // TODO: This does not sound quite right + for sample in channel_samples.into_iter() { + let noise = self.prng.next_f32() * 2.0 - 1.0; + let am = *sample * noise; + + *sample += am * amount; } } diff --git a/plugins/crisp/src/pcg.rs b/plugins/crisp/src/pcg.rs index 1b20a37a..d6dac5b1 100644 --- a/plugins/crisp/src/pcg.rs +++ b/plugins/crisp/src/pcg.rs @@ -65,7 +65,7 @@ impl Pcg32iState { .wrapping_mul(PCG_DEFAULT_MULTIPLIER_32) .wrapping_add(self.inc); - let word = ((old_state >> ((old_state >> 28) + 4)) ^ old_state) * 277803737; + let word = ((old_state >> ((old_state >> 28) + 4)) ^ old_state).wrapping_mul(277803737); (word >> 22) ^ word }