finished noise implementation

This commit is contained in:
Weird Constructor 2021-07-01 05:06:46 +02:00
parent bada6377ee
commit fb3bb7dab2
3 changed files with 194 additions and 48 deletions

View file

@ -499,7 +499,7 @@ macro_rules! node_list {
(2 g n_id d_id r_id f_def stp_d -1.0, 1.0, 0.7)
[0 sig],
noise => Noise UIType::Generic UICategory::Osc
(0 atv n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)
(0 atv n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0)
(1 offs n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)
{2 0 mode setting(0) fa_noise_mode 0 1}
[0 sig],

View file

@ -4,7 +4,7 @@
use crate::nodes::{NodeAudioContext, NodeExecContext};
use crate::dsp::{NodeId, SAtom, ProcBuf, DspNode, LedPhaseVals};
//use crate::dsp::helpers::};
use crate::dsp::helpers::Rng;
#[macro_export]
macro_rules! fa_noise_mode { ($formatter: expr, $v: expr, $denorm_v: expr) => { {
@ -20,22 +20,35 @@ macro_rules! fa_noise_mode { ($formatter: expr, $v: expr, $denorm_v: expr) => {
/// A simple amplifier
#[derive(Debug, Clone)]
pub struct Noise {
seed: u64,
rng: Rng,
}
impl Noise {
pub fn new(_nid: &NodeId) -> Self {
pub fn new(nid: &NodeId) -> Self {
let mut rng = Rng::new();
rng.seed(
(0x193a67f4a8a6d769_u64).wrapping_add(
0x131415 * (nid.instance() as u64 + 1)));
Self {
seed: nid.instance() as u64,
rng,
}
}
pub const atv : &'static str =
"Noise atv\n...\nRange: (-1..1)";
"Noise atv\n.Attenuverter input, to attenuate or inverter \
the noise.\nRange: (-1..1)";
pub const offs : &'static str =
"Noise offs\n...\nRange: (-1..1)";
"Noise offs\n.Offset input, that is added to the output \
signal after attenuvertig it.\nRange: (-1..1)";
pub const mode : &'static str =
"Noise mode\n...";
"Noise mode\nYou can switch between 'Bipolar' noise, which \
uses the full range from -1 to 1, or 'Unipolar' noise that \
only uses the range from 0 to 1.";
pub const sig : &'static str =
"Noise sig\nThe output of the dry/wet mix.\nRange: (-1..1)";
"Noise sig\nThe noise output.\nRange: (-1..1)";
pub const DESC : &'static str =
r#"A Simple Noise Oscillator
@ -59,10 +72,13 @@ unipolar and bipolar output.
impl DspNode for Noise {
fn outputs() -> usize { 1 }
fn set_sample_rate(&mut self, srate: f32) {
fn set_sample_rate(&mut self, _srate: f32) {
}
fn reset(&mut self) {
self.rng.seed(
(0x193a67f4a8a6d769_u64).wrapping_add(
0x131415 * (self.seed + 1)));
}
#[inline]
@ -73,47 +89,32 @@ impl DspNode for Noise {
{
use crate::dsp::{at, out, inp, denorm};
// let buffer = &mut *self.buffer;
//
// let mode = at::Delay::mode(atoms);
// let inp = inp::Delay::inp(inputs);
// let trig = inp::Delay::trig(inputs);
// let time = inp::Delay::time(inputs);
// let fb = inp::Delay::fb(inputs);
// let mix = inp::Delay::mix(inputs);
// let out = out::Delay::sig(outputs);
let mode = at::Noise::mode(atoms);
let atv = inp::Noise::atv(inputs);
let offs = inp::Noise::offs(inputs);
let out = out::Noise::sig(outputs);
// if mode.i() == 0 {
// for frame in 0..ctx.nframes() {
// let dry = inp.read(frame);
//
// let out_sample =
// buffer.cubic_interpolate_at(
// denorm::Delay::time(time, frame));
//
// buffer.feed(dry + out_sample * denorm::Delay::fb(fb, frame));
//
// out.write(frame,
// crossfade(dry, out_sample,
// denorm::Delay::mix(mix, frame).clamp(0.0, 1.0)));
// }
// } else {
// for frame in 0..ctx.nframes() {
// let dry = inp.read(frame);
//
// let clock_samples =
// self.clock.next(denorm::Delay::trig(trig, frame));
// let out_sample = buffer.at(clock_samples as usize);
//
// buffer.feed(dry + out_sample * denorm::Delay::fb(fb, frame));
//
// out.write(frame,
// crossfade(dry, out_sample,
// denorm::Delay::mix(mix, frame).clamp(0.0, 1.0)));
// }
// }
let rng = &mut self.rng;
// let last_frame = ctx.nframes() - 1;
// ctx_vals[0].set(out.read(last_frame));
if mode.i() == 0 {
for frame in 0..ctx.nframes() {
let s = (rng.next() * 2.0) - 1.0;
let s = s
* denorm::Noise::atv(atv, frame)
+ denorm::Noise::offs(offs, frame);
out.write(frame, s);
}
} else {
for frame in 0..ctx.nframes() {
let s = rng.next()
* denorm::Noise::atv(atv, frame)
+ denorm::Noise::offs(offs, frame);
out.write(frame, s);
}
}
let last_frame = ctx.nframes() - 1;
ctx_vals[0].set(out.read(last_frame));
}
}

145
tests/node_noise.rs Normal file
View file

@ -0,0 +1,145 @@
mod common;
use common::*;
#[test]
fn check_node_noise_bipolar() {
let (node_conf, mut node_exec) = new_node_engine();
let mut matrix = Matrix::new(node_conf, 3, 3);
let noise = NodeId::Noise(0);
let out = NodeId::Out(0);
matrix.place(0, 0, Cell::empty(noise)
.out(None, None, noise.out("sig")));
matrix.place(0, 1, Cell::empty(out)
.input(out.inp("ch1"), None, None));
matrix.sync().unwrap();
let (out_l, _) = run_for_ms(&mut node_exec, 25.0);
assert_float_eq!(out_l[0], 0.1545);
assert_float_eq!(out_l[10], 0.5924);
assert_float_eq!(out_l[11], -0.3643);
let rms_mimax = calc_rms_mimax_each_ms(&out_l[..], 10.0);
assert_rmsmima!(rms_mimax[0], (0.3374, -0.9958, 0.9971));
assert_rmsmima!(rms_mimax[1], (0.3384, -0.9997, 0.9993));
}
#[test]
fn check_node_noise_seed() {
let (node_conf, mut node_exec) = new_node_engine();
let mut matrix = Matrix::new(node_conf, 3, 3);
let noise = NodeId::Noise(0);
let nois2 = NodeId::Noise(1);
let out = NodeId::Out(0);
matrix.place(0, 0, Cell::empty(noise)
.out(None, None, noise.out("sig")));
matrix.place(0, 1, Cell::empty(out)
.input(out.inp("ch1"), None, None));
matrix.place(1, 0, Cell::empty(nois2)
.out(None, None, nois2.out("sig")));
matrix.place(1, 1, Cell::empty(out)
.input(out.inp("ch2"), None, None));
matrix.sync().unwrap();
let (out_l, out_r) = run_for_ms(&mut node_exec, 25.0);
assert_float_eq!(out_l[0], 0.1545);
assert_float_eq!(out_l[10], 0.5924);
assert_float_eq!(out_r[0], -0.2156);
assert_float_eq!(out_r[10], 0.9441);
}
#[test]
fn check_node_noise_unipolar() {
let (node_conf, mut node_exec) = new_node_engine();
let mut matrix = Matrix::new(node_conf, 3, 3);
let noise = NodeId::Noise(0);
let out = NodeId::Out(0);
matrix.place(0, 0, Cell::empty(noise)
.out(None, None, noise.out("sig")));
matrix.place(0, 1, Cell::empty(out)
.input(out.inp("ch1"), None, None));
pset_s(&mut matrix, noise, "mode", 1);
matrix.sync().unwrap();
let (out_l, _) = run_for_ms(&mut node_exec, 25.0);
assert_float_eq!(out_l[0], 0.5772);
assert_float_eq!(out_l[10], 0.7962);
assert_float_eq!(out_l[11], 0.3178);
let rms_mimax = calc_rms_mimax_each_ms(&out_l[..], 10.0);
assert_rmsmima!(rms_mimax[0], (0.3214, 0.002, 0.9985));
assert_rmsmima!(rms_mimax[1], (0.3373, 0.0001, 0.9996));
}
#[test]
fn check_node_noise_atv_offs() {
let (node_conf, mut node_exec) = new_node_engine();
let mut matrix = Matrix::new(node_conf, 3, 3);
let noise = NodeId::Noise(0);
let out = NodeId::Out(0);
matrix.place(0, 0, Cell::empty(noise)
.out(None, None, noise.out("sig")));
matrix.place(0, 1, Cell::empty(out)
.input(out.inp("ch1"), None, None));
pset_s(&mut matrix, noise, "mode", 1);
pset_n(&mut matrix, noise, "atv", 0.5);
pset_n(&mut matrix, noise, "offs", 0.3);
matrix.sync().unwrap();
let (out_l, _) = run_for_ms(&mut node_exec, 100.0);
let rms_mimax = calc_rms_mimax_each_ms(&out_l[..], 100.0);
println!("mima {:?}", rms_mimax);
assert_rmsmima!(rms_mimax[0], (0.3223, 0.3, 0.7998));
}
#[test]
fn check_node_noise_atv_offs_2() {
let (node_conf, mut node_exec) = new_node_engine();
let mut matrix = Matrix::new(node_conf, 3, 3);
let noise = NodeId::Noise(0);
let out = NodeId::Out(0);
matrix.place(0, 0, Cell::empty(noise)
.out(None, None, noise.out("sig")));
matrix.place(0, 1, Cell::empty(out)
.input(out.inp("ch1"), None, None));
pset_s(&mut matrix, noise, "mode", 1);
pset_n(&mut matrix, noise, "atv", -0.5);
pset_n(&mut matrix, noise, "offs", -0.4);
matrix.sync().unwrap();
let (out_l, _) = run_for_ms(&mut node_exec, 100.0);
let rms_mimax = calc_rms_mimax_each_ms(&out_l[..], 100.0);
println!("mima {:?}", rms_mimax);
assert_rmsmima!(rms_mimax[0], (0.4422, -0.8998, -0.4));
}
#[test]
fn check_node_noise_atv_offs_bipolar() {
let (node_conf, mut node_exec) = new_node_engine();
let mut matrix = Matrix::new(node_conf, 3, 3);
let noise = NodeId::Noise(0);
let out = NodeId::Out(0);
matrix.place(0, 0, Cell::empty(noise)
.out(None, None, noise.out("sig")));
matrix.place(0, 1, Cell::empty(out)
.input(out.inp("ch1"), None, None));
pset_s(&mut matrix, noise, "mode", 0);
pset_n(&mut matrix, noise, "atv", 0.5);
pset_n(&mut matrix, noise, "offs", 0.4);
matrix.sync().unwrap();
let (out_l, _) = run_for_ms(&mut node_exec, 100.0);
let rms_mimax = calc_rms_mimax_each_ms(&out_l[..], 100.0);
println!("mima {:?}", rms_mimax);
assert_rmsmima!(rms_mimax[0], (0.2407, -0.0998, 0.8996));
}