implemented a Comb filter

This commit is contained in:
Weird Constructor 2021-08-06 05:05:47 +02:00
parent 210d542af5
commit da08c8d85e
4 changed files with 131 additions and 3 deletions

View file

@ -799,7 +799,8 @@ impl Comb {
#[inline]
pub fn next_feedback(&mut self, time: f32, g: f32, v: f32) -> f32 {
let s = self.delay.cubic_interpolate_at(time);
self.delay.feed(v + s * g);
let v = v + s * g;
self.delay.feed(v);
v
}

View file

@ -38,6 +38,8 @@ mod node_bosc;
mod node_vosc;
#[allow(non_upper_case_globals)]
mod node_biqfilt;
#[allow(non_upper_case_globals)]
mod node_comb;
pub mod biquad;
pub mod tracker;
@ -73,6 +75,7 @@ use crate::fa_biqfilt_type;
use crate::fa_biqfilt_ord;
use crate::fa_vosc_ovrsmpl;
use crate::fa_distort;
use crate::fa_comb_mode;
use node_amp::Amp;
use node_sin::Sin;
@ -93,6 +96,7 @@ use node_mix3::Mix3;
use node_bosc::BOsc;
use node_vosc::VOsc;
use node_biqfilt::BiqFilt;
use node_comb::Comb;
pub const MIDI_MAX_FREQ : f32 = 13289.75;
@ -489,7 +493,7 @@ define_exp!{n_declick d_declick 0.0, 50.0}
define_exp!{n_env d_env 0.0, 1000.0}
define_exp!{n_time d_time 0.5, 5000.0}
define_exp!{n_ftme d_ftme 0.25, 1000.0}
define_exp!{n_ftme d_ftme 0.1, 1000.0}
// Special linear gain factor for the Out node, to be able
// to reach more exact "1.0".
@ -641,6 +645,12 @@ macro_rules! node_list {
(1 time n_ftme d_ftme r_fms f_ms stp_m 0.0, 1.0, 25.0)
(2 g n_id d_id r_id f_def stp_d -1.0, 1.0, 0.7)
[0 sig],
comb => Comb UIType::Generic UICategory::Signal
(0 inp n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)
(1 time n_ftme d_ftme r_fms f_ms stp_m 0.0, 1.0, 25.0)
(2 g n_id d_id r_id f_def stp_d -1.0, 1.0, 0.7)
{3 0 mode setting(0) fa_comb_mode 0 1}
[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.5)
(1 offs n_id d_id r_s f_def stp_d -1.0, 1.0, 0.0)

116
src/dsp/node_comb.rs Normal file
View file

@ -0,0 +1,116 @@
// 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::{NodeId, SAtom, ProcBuf, DspNode, LedPhaseVals, NodeContext};
use crate::dsp::helpers;
#[macro_export]
macro_rules! fa_comb_mode { ($formatter: expr, $v: expr, $denorm_v: expr) => { {
let s =
match ($v.round() as usize) {
0 => "FedBack",
1 => "FedForw",
_ => "?",
};
write!($formatter, "{}", s)
} } }
/// A simple amplifier
#[derive(Debug, Clone)]
pub struct Comb {
comb: Box<helpers::Comb>,
}
impl Comb {
pub fn new(_nid: &NodeId) -> Self {
Self {
comb: Box::new(helpers::Comb::new()),
}
}
pub const inp : &'static str =
"Comb inp\nThe signal input for the comb filter.\nRange: (-1..1)";
pub const g : &'static str =
"Comb g\nThe internal factor for the comb filter.\nRange: (-1..1)";
pub const time : &'static str =
"Comb time\nThe comb delay time.\nRange: (0..1)";
pub const sig : &'static str =
"Comb sig\nThe output of comb filter.\nRange: (-1..1)";
pub const mode : &'static str =
"Comb mode\nThe mode of the comb filter, whether it's a \
feedback or feedforward comb filter.";
pub const DESC : &'static str =
r#"Comb Filter
A very simple comb filter. It has interesting filtering effects
and can be used to build custom reverbs.
"#;
pub const HELP : &'static str =
r#"Comb - A Simple Comb Filter
This is a comb filter that can be used for filtering
as well as for building reverbs or anything you might
find it useful for.
For typical arrangements in combination with allpass filters,
see the documentation of the 'Comb' node!
"#;
}
impl DspNode for Comb {
fn outputs() -> usize { 1 }
fn set_sample_rate(&mut self, srate: f32) {
self.comb.set_sample_rate(srate);
}
fn reset(&mut self) {
self.comb.reset();
}
#[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, at};
let inp = inp::Comb::inp(inputs);
let time = inp::Comb::time(inputs);
let g = inp::Comb::g(inputs);
let out = out::Comb::sig(outputs);
let mode = at::Comb::mode(atoms);
let c = &mut *self.comb;
if mode.i() == 0 {
for frame in 0..ctx.nframes() {
let v = inp.read(frame);
out.write(frame,
c.next_feedback(
denorm::Comb::time(time, frame),
denorm::Comb::g(g, frame),
v));
}
} else {
for frame in 0..ctx.nframes() {
let v = inp.read(frame);
out.write(frame,
c.next_feedforward(
denorm::Comb::time(time, frame),
denorm::Comb::g(g, frame),
v));
}
}
let last_frame = ctx.nframes() - 1;
ctx_vals[0].set(out.read(last_frame));
}
}

View file

@ -122,7 +122,8 @@ Next page: more filters (eg. Moog)
SFilter - Simple Audio Filter Collection
For a more colored filter reach for the Stilson/Moog filter with a 24dB
fall off per octave.
fall off per octave. Beware high cutoff frequencies for this filter,
as it can become quite unstable.
LP 24m - Low-pass Stilson/Moog filter (24dB)
HP 24m - High-pass Stilson/Moog filter (24dB)