finished noise implementation
This commit is contained in:
parent
bada6377ee
commit
fb3bb7dab2
3 changed files with 194 additions and 48 deletions
|
@ -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],
|
||||
|
|
|
@ -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
145
tests/node_noise.rs
Normal 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));
|
||||
}
|
Loading…
Reference in a new issue