started work on RndWlk node, for a triggered noise source

This commit is contained in:
Weird Constructor 2021-08-12 22:12:24 +02:00
parent cd41a16894
commit f63292f9db
3 changed files with 226 additions and 1 deletions

View file

@ -44,6 +44,8 @@ mod node_comb;
mod node_tslfo;
#[allow(non_upper_case_globals)]
mod node_pverb;
#[allow(non_upper_case_globals)]
mod node_rndwlk;
pub mod biquad;
pub mod tracker;
@ -104,6 +106,7 @@ use node_biqfilt::BiqFilt;
use node_comb::Comb;
use node_tslfo::TsLfo;
use node_pverb::PVerb;
use node_rndwlk::RndWlk;
pub const MIDI_MAX_FREQ : f32 = 13289.75;
@ -413,6 +416,21 @@ macro_rules! r_fms { ($x: expr, $coarse: expr) => {
}
} }
/// The rounding function for milliseconds knobs that also have a 0.0 setting
macro_rules! r_fmz { ($x: expr, $coarse: expr) => {
if $coarse {
if d_ftmz!($x) > 1000.0 {
n_ftmz!((d_ftmz!($x) / 100.0).round() * 100.0)
} else if d_ftmz!($x) > 100.0 {
n_ftmz!((d_ftmz!($x) / 10.0).round() * 10.0)
} else {
n_ftmz!((d_ftmz!($x)).round())
}
} else {
n_ftmz!((d_ftmz!($x) * 10.0).round() / 10.0)
}
} }
/// The rounding function for freq knobs (n_pit / d_pit)
macro_rules! r_fq { ($x: expr, $coarse: expr) => {
if $coarse {
@ -592,6 +610,7 @@ define_exp!{n_env d_env 0.0, 1000.0}
define_exp6!{n_lfot d_lfot 0.1,300000.0}
define_exp!{n_time d_time 0.5, 5000.0}
define_exp!{n_ftme d_ftme 0.1, 1000.0}
define_exp!{n_ftmz d_ftmz 0.0, 1000.0}
// Special linear gain factor for the Out node, to be able
// to reach more exact "1.0".
@ -735,6 +754,14 @@ macro_rules! node_list {
(1 trig n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)
(2 rev n_id d_id r_id f_def stp_d 0.0, 1.0, 0.5)
[0 sig],
rndwlk => RndWlk UIType::Generic UICategory::Mod
(0 trig n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)
(1 step n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)
(2 offs n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)
(3 min n_id d_id r_id f_def stp_d 0.0, 1.0, 0.0)
(4 max n_id d_id r_id f_def stp_d 0.0, 1.0, 0.0)
(5 slewt n_ftmz d_ftmz r_fmz f_ms stp_m 0.0, 1.0, 10.0)
[0 sig],
delay => Delay UIType::Generic UICategory::Signal
(0 inp n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)
(1 trig n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)

View file

@ -17,7 +17,7 @@ macro_rules! fa_noise_mode { ($formatter: expr, $v: expr, $denorm_v: expr) => {
write!($formatter, "{}", s)
} } }
/// A simple amplifier
/// A simple noise generator
#[derive(Debug, Clone)]
pub struct Noise {
seed: u64,

198
src/dsp/node_rndwlk.rs Normal file
View file

@ -0,0 +1,198 @@
// Copyright (c) 2021 Weird Constructor <weirdconstructor@gmail.com>
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
// See README.md and COPYING for details.
use crate::nodes::{NodeAudioContext, NodeExecContext};
use crate::dsp::helpers::Rng;
use crate::dsp::{
NodeId, SAtom, ProcBuf, DspNode, LedPhaseVals, NodeContext,
GraphAtomData, GraphFun,
};
/// A triggered random walker
#[derive(Debug, Clone)]
pub struct RndWlk {
israte_ms: f64,
rng: Rng,
target: f64,
target_inc: f64,
current: f64,
}
impl RndWlk {
pub fn new(nid: &NodeId) -> Self {
let mut rng = Rng::new();
rng.seed(
(0x193a67f4a8a6d769_u64).wrapping_add(
0x262829 * (nid.instance() as u64 + 1)));
Self {
rng,
israte_ms: 1.0 / 44100.0,
target: 0.0,
target_inc: 0.0,
current: 0.0,
}
}
pub const trig : &'static str =
"RndWlk trig\n\n\nRange: (-1..1)";
pub const step : &'static str =
"RndWlk step\n\nRange: (-1..1)";
pub const offs : &'static str =
"RndWlk offs\n\nRange: (-1..1)";
pub const min : &'static str =
"RndWlk min\n\nRange: (0..1)";
pub const max : &'static str =
"RndWlk max\n\nRange: (0..1)";
pub const slewt : &'static str =
"RndWlk slewt\n\nRange: (0..1)";
pub const sig : &'static str =
"RndWlk sig\nOscillator output\nRange: (-1..1)\n";
pub const DESC : &'static str =
r#"Random Walker
"#;
pub const HELP : &'static str =
r#"RndWlk - Random Walker
"#;
}
impl DspNode for RndWlk {
fn outputs() -> usize { 1 }
fn set_sample_rate(&mut self, srate: f32) {
self.israte_ms = (1.0 / (srate as f64)) / 1000.0;
}
fn reset(&mut self) {
self.target = 0.0;
self.current = 0.0;
}
#[inline]
fn process<T: NodeAudioContext>(
&mut self, ctx: &mut T, _ectx: &mut NodeExecContext,
_nctx: &NodeContext,
atoms: &[SAtom], inputs: &[ProcBuf],
outputs: &mut [ProcBuf], ctx_vals: LedPhaseVals)
{
use crate::dsp::{out, inp, denorm, denorm_offs, at};
// if trigger
// - initialize target
//
// let min = min.clamp(0.0, 1.0);
// let max = max.clamp(0.0, 1.0);
// if min > max {
// std::mem::swap(&mut min, &mut max);
// }
// let delta = (max - min).clamp(0.0001, 1.0);
//
// if self.trigger.check... {
// let step = step.clamp(-1.0, 1.0);
// let offs = offs.clamp(-1.0, 1.0);
// self.target = self.rng.next() as f64 * step + offs;
//
// if slew_time_ms < 0.01 {
// self.current = self.target;
// self.current = ((self.current - min) % delta).abs() + min;
// } else {
// let slew_samples = slew_time_ms * self.israte_ms;
// self.target_inc = self.target / slew_samples;
// }
// }
//
// if self.target_inc > 0.0 {
// self.current += self.target_inc;
// if (self.current - self.target).abs() < 0.00001 {
// self.target_inc = 0.0;
// self.current = self.target;
// }
// self.current = ((self.current - min) % delta).abs() + min;
// }
// let freq = inp::RndWlk::freq(inputs);
// let det = inp::RndWlk::det(inputs);
// let d = inp::RndWlk::d(inputs);
// let v = inp::RndWlk::v(inputs);
// let vs = inp::RndWlk::vs(inputs);
// let damt = inp::RndWlk::damt(inputs);
let out = out::RndWlk::sig(outputs);
// let ovrsmpl = at::RndWlk::ovrsmpl(atoms);
// let dist = at::RndWlk::dist(atoms);
//
// let israte_ms = self.israte;
//
// let dist = dist.i() as u8;
// let oversample = ovrsmpl.i() == 1;
//
// let mut osc = &mut self.osc;
//
// if oversample {
// for frame in 0..ctx.nframes() {
// let freq = denorm_offs::RndWlk::freq(freq, det.read(frame), frame);
// let v = denorm::RndWlk::v(v, frame).clamp(0.0, 1.0);
// let d = denorm::RndWlk::d(d, frame).clamp(0.0, 1.0);
// let vs = denorm::RndWlk::vs(vs, frame).clamp(0.0, 20.0);
// let damt = denorm::RndWlk::damt(damt, frame).clamp(0.0, 1.0);
//
// let v = VPSOscillator::limit_v(d, v + vs);
//
// let overbuf = self.oversampling.resample_buffer();
// for b in overbuf {
// let s = osc.next(freq, israte, d, v);
// *b = apply_distortion(s, damt, dist);
// }
//
// out.write(frame, self.oversampling.downsample());
// }
//
// } else {
// for frame in 0..ctx.nframes() {
// let freq = denorm_offs::RndWlk::freq(freq, det.read(frame), frame);
// let v = denorm::RndWlk::v(v, frame).clamp(0.0, 1.0);
// let d = denorm::RndWlk::d(d, frame).clamp(0.0, 1.0);
// let vs = denorm::RndWlk::vs(vs, frame).clamp(0.0, 20.0);
// let damt = denorm::RndWlk::damt(damt, frame).clamp(0.0, 1.0);
//
// let v = VPSOscillator::limit_v(d, v + vs);
// let s = osc.next(freq, israte * (OVERSAMPLING as f32), d, v);
// let s = apply_distortion(s, damt, dist);
//
// out.write(frame, s);
// }
// }
ctx_vals[0].set(out.read(ctx.nframes() - 1));
}
// fn graph_fun() -> Option<GraphFun> {
// let mut osc = VPSOscillator::new(0.0);
// let israte = 1.0 / 128.0;
//
// Some(Box::new(move |gd: &dyn GraphAtomData, init: bool, _x: f32, _xn: f32| -> f32 {
// if init {
// osc.reset();
// }
//
// let v = NodeId::RndWlk(0).inp_param("v").unwrap().inp();
// let vs = NodeId::RndWlk(0).inp_param("vs").unwrap().inp();
// let d = NodeId::RndWlk(0).inp_param("d").unwrap().inp();
// let damt = NodeId::RndWlk(0).inp_param("damt").unwrap().inp();
// let dist = NodeId::RndWlk(0).inp_param("dist").unwrap().inp();
//
// let v = gd.get_denorm(v as u32).clamp(0.0, 1.0);
// let d = gd.get_denorm(d as u32).clamp(0.0, 1.0);
// let vs = gd.get_denorm(vs as u32).clamp(0.0, 20.0);
// let damt = gd.get_denorm(damt as u32);
// let dist = gd.get(dist as u32).map(|a| a.i()).unwrap_or(0);
//
// let v = VPSOscillator::limit_v(d, v + vs);
// let s = osc.next(1.0, israte, d, v);
// let s = apply_distortion(s, damt, dist as u8);
//
// (s + 1.0) * 0.5
// }))
// }
}