implemented untested DSP part of Delay

This commit is contained in:
Weird Constructor 2021-06-19 12:17:22 +02:00
parent 9e752fe3f1
commit cbc69f3ca3
3 changed files with 47 additions and 17 deletions

View file

@ -160,10 +160,12 @@ impl SplitMix64 {
} }
} }
pub fn mix(v1: f32, v2: f32, mix: f32) -> f32 { #[inline]
pub fn crossfade(v1: f32, v2: f32, mix: f32) -> f32 {
v1 * (1.0 - mix) + v2 * mix v1 * (1.0 - mix) + v2 * mix
} }
#[inline]
pub fn clamp(f: f32, min: f32, max: f32) -> f32 { pub fn clamp(f: f32, min: f32, max: f32) -> f32 {
if f < min { min } if f < min { min }
else if f > max { max } else if f > max { max }
@ -482,7 +484,8 @@ impl TriggerClock {
/// Default size of the delay buffer: 5 seconds at 8 times 48kHz /// Default size of the delay buffer: 5 seconds at 8 times 48kHz
const DEFAULT_DELAY_BUFFER_SAMPLES : usize = 8 * 48000 * 5; const DEFAULT_DELAY_BUFFER_SAMPLES : usize = 8 * 48000 * 5;
struct DelayBuffer { #[derive(Debug, Clone)]
pub struct DelayBuffer {
data: Vec<f32>, data: Vec<f32>,
wr: usize, wr: usize,
srate: f32, srate: f32,

View file

@ -363,10 +363,11 @@ define_exp!{n_declick d_declick 0.0, 50.0}
define_exp!{n_env d_env 0.0, 1000.0} define_exp!{n_env d_env 0.0, 1000.0}
define_exp!{n_time d_time 0.0, 5000.0}
// Special linear gain factor for the Out node, to be able // Special linear gain factor for the Out node, to be able
// to reach more exact "1.0". // to reach more exact "1.0".
define_lin!{n_ogin d_ogin 0.0, 2.0} define_lin!{n_ogin d_ogin 0.0, 2.0}
define_lin!{n_time d_time 0.0, 5000.0}
// A note about the input-indicies: // A note about the input-indicies:
// //

View file

@ -3,7 +3,8 @@
// See README.md and COPYING for details. // See README.md and COPYING for details.
use crate::nodes::{NodeAudioContext, NodeExecContext}; use crate::nodes::{NodeAudioContext, NodeExecContext};
use crate::dsp::{NodeId, SAtom, ProcBuf, GraphFun, GraphAtomData, DspNode, LedPhaseVals}; use crate::dsp::{NodeId, SAtom, ProcBuf, DspNode, LedPhaseVals};
use crate::dsp::helpers::{DelayBuffer, crossfade};
#[macro_export] #[macro_export]
macro_rules! fa_dly_s { ($formatter: expr, $v: expr, $denorm_v: expr) => { { macro_rules! fa_dly_s { ($formatter: expr, $v: expr, $denorm_v: expr) => { {
@ -28,11 +29,15 @@ macro_rules! fa_dly_s { ($formatter: expr, $v: expr, $denorm_v: expr) => { {
/// A simple amplifier /// A simple amplifier
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Delay { pub struct Delay {
buffer: Box<DelayBuffer>,
fb_sample: f32,
} }
impl Delay { impl Delay {
pub fn new(_nid: &NodeId) -> Self { pub fn new(_nid: &NodeId) -> Self {
Self { Self {
buffer: Box::new(DelayBuffer::new()),
fb_sample: 0.0,
} }
} }
@ -75,27 +80,48 @@ For other kinds of delay/feedback please see also the 'FbWr'/'FbRd' nodes.
impl DspNode for Delay { impl DspNode for Delay {
fn outputs() -> usize { 1 } 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.buffer.set_sample_rate(srate);
}
fn reset(&mut self) {
self.buffer.reset();
}
#[inline] #[inline]
fn process<T: NodeAudioContext>( fn process<T: NodeAudioContext>(
&mut self, ctx: &mut T, _ectx: &mut NodeExecContext, &mut self, ctx: &mut T, _ectx: &mut NodeExecContext,
atoms: &[SAtom], _params: &[ProcBuf], _inputs: &[ProcBuf], _atoms: &[SAtom], _params: &[ProcBuf], inputs: &[ProcBuf],
outputs: &mut [ProcBuf], _led: LedPhaseVals) outputs: &mut [ProcBuf], _led: LedPhaseVals)
{ {
use crate::dsp::{out, at}; use crate::dsp::{out, inp, denorm};
// let p = at::Delay::p(atoms); let buffer = &mut *self.buffer;
let inp = inp::Delay::inp(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 out = out::Delay::sig(outputs);
for frame in 0..ctx.nframes() {
out.write(frame, 0.0);
}
}
fn graph_fun() -> Option<GraphFun> { let mut fb_s = self.fb_sample;
Some(Box::new(|_gd: &dyn GraphAtomData, _init: bool, x: f32| -> f32 {
x for frame in 0..ctx.nframes() {
})) let dry = inp.read(frame);
buffer.feed(
dry + fb_s * denorm::Delay::fb(fb, frame));
let out_sample =
buffer.cubic_interpolate_at(
denorm::Delay::time(time, frame));
out.write(frame,
crossfade(dry, out_sample,
denorm::Delay::mix(mix, frame).clamp(0.0, 1.0)));
fb_s = out_sample;
}
self.fb_sample = fb_s;
} }
} }