only frequency test left + description
This commit is contained in:
parent
22aa19cf9f
commit
c656b40729
30 changed files with 213 additions and 69 deletions
|
@ -2,11 +2,11 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::{sqrt4_to_pow4, TrigSignal, Trigger};
|
|
||||||
use crate::dsp::{
|
use crate::dsp::{
|
||||||
DspNode, GraphAtomData, GraphFun, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
DspNode, GraphAtomData, GraphFun, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
||||||
};
|
};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::{sqrt4_to_pow4, TrigSignal, Trigger};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_ad_mult {
|
macro_rules! fa_ad_mult {
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::AllPass;
|
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::AllPass;
|
||||||
|
|
||||||
/// A simple amplifier
|
/// A simple amplifier
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::*;
|
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::*;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_biqfilt_type {
|
macro_rules! fa_biqfilt_type {
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::PolyBlepOscillator;
|
|
||||||
use crate::dsp::{
|
use crate::dsp::{
|
||||||
DspNode, GraphAtomData, GraphFun, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
DspNode, GraphAtomData, GraphFun, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
||||||
};
|
};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::PolyBlepOscillator;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_bosc_wtype {
|
macro_rules! fa_bosc_wtype {
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::{DelayBuffer, FixedOnePole, Biquad};
|
|
||||||
use crate::dsp::{
|
use crate::dsp::{
|
||||||
denorm, denorm_offs, inp, out, DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
denorm, denorm_offs, inp, out, DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
||||||
};
|
};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::{Biquad, DelayBuffer, FixedOnePole};
|
||||||
|
|
||||||
// Bowed String instrument oscillator
|
// Bowed String instrument oscillator
|
||||||
// Bowed string model, a la Smith (1986),
|
// Bowed string model, a la Smith (1986),
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp;
|
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_comb_mode {
|
macro_rules! fa_comb_mode {
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::{ChangeTrig, CtrlPitchQuantizer};
|
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::{ChangeTrig, CtrlPitchQuantizer};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_cqnt {
|
macro_rules! fa_cqnt {
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::{crossfade, DelayBuffer, TriggerSampleClock};
|
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::{crossfade, DelayBuffer, TriggerSampleClock};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_delay_mode {
|
macro_rules! fa_delay_mode {
|
||||||
|
|
|
@ -69,14 +69,17 @@ impl DspNode for Formant {
|
||||||
let decay_freq = denorm::Formant::dcy(decay_freq, frame);
|
let decay_freq = denorm::Formant::dcy(decay_freq, frame);
|
||||||
|
|
||||||
// where the two decays meet
|
// where the two decays meet
|
||||||
let carrier_center = attack_freq / (attack_freq + decay_freq);
|
// clamp to avoid division by 0
|
||||||
|
let carrier_center =
|
||||||
|
(attack_freq / (attack_freq + decay_freq)).max(1e-6).min(1.0 - 1e-6);
|
||||||
|
|
||||||
// where they meet in amplitude
|
// where they meet in amplitude
|
||||||
let carrier_lowest_amplitude = if carrier_center * decay_freq > base_freq * 2.0 {
|
let carrier_lowest_amplitude =
|
||||||
0.0
|
if carrier_center * decay_freq > base_freq * 2.0 || base_freq == 0.0 {
|
||||||
} else {
|
0.0
|
||||||
(-(std::f32::consts::PI * carrier_center * decay_freq) / base_freq).exp()
|
} else {
|
||||||
};
|
(-(std::f32::consts::PI * carrier_center * decay_freq) / base_freq).exp()
|
||||||
|
};
|
||||||
|
|
||||||
// make a triangle wave, with the peak at carrier center
|
// make a triangle wave, with the peak at carrier center
|
||||||
let carrier_base =
|
let carrier_base =
|
||||||
|
@ -88,17 +91,22 @@ impl DspNode for Formant {
|
||||||
* (carrier_base * carrier_base * (3.0 - 2.0 * carrier_base)));
|
* (carrier_base * carrier_base * (3.0 - 2.0 * carrier_base)));
|
||||||
|
|
||||||
// multiple of the frequency the modulators are at
|
// multiple of the frequency the modulators are at
|
||||||
let multiple = formant_freq / base_freq;
|
let multiple = formant_freq / base_freq.max(1e-6);
|
||||||
|
|
||||||
// round them to the closest integer of the formant freq
|
// round them to the closest integer of the formant freq
|
||||||
let freq_a = multiple.floor().max(1.0);
|
let freq_a = multiple.floor();
|
||||||
let freq_b = freq_a + 1.0;
|
let freq_b = freq_a + 1.0;
|
||||||
|
|
||||||
// and how much to lerp between them
|
// and how much to lerp between them
|
||||||
let blend = multiple.max(1.0).fract();
|
let blend = multiple.fract();
|
||||||
|
|
||||||
// get the true modulator
|
// get the true modulator
|
||||||
let modulator = (1.0 - blend) * (std::f32::consts::TAU * self.phase * freq_a).cos()
|
let modulator = (1.0 - blend)
|
||||||
|
* if multiple < 1.0 {
|
||||||
|
0.0
|
||||||
|
} else {
|
||||||
|
(std::f32::consts::TAU * self.phase * freq_a).cos()
|
||||||
|
}
|
||||||
+ blend * (std::f32::consts::TAU * self.phase * freq_b).cos();
|
+ blend * (std::f32::consts::TAU * self.phase * freq_b).cos();
|
||||||
|
|
||||||
// entire wave
|
// entire wave
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::Trigger;
|
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::Trigger;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_mux9_in_cnt {
|
macro_rules! fa_mux9_in_cnt {
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::Rng;
|
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::Rng;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_noise_mode {
|
macro_rules! fa_noise_mode {
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::{DattorroReverb, DattorroReverbParams, crossfade};
|
|
||||||
use crate::dsp::{denorm, DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{denorm, DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::{crossfade, DattorroReverb, DattorroReverbParams};
|
||||||
|
|
||||||
pub struct DatParams {
|
pub struct DatParams {
|
||||||
frame: usize,
|
frame: usize,
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::{ChangeTrig, Quantizer};
|
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::{ChangeTrig, Quantizer};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_quant {
|
macro_rules! fa_quant {
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::{Rng, SlewValue, Trigger};
|
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::{Rng, SlewValue, Trigger};
|
||||||
|
|
||||||
/// A triggered random walker
|
/// A triggered random walker
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::{cubic_interpolate, Trigger};
|
|
||||||
use crate::dsp::{at, denorm, denorm_offs, inp, out}; //, inp, denorm, denorm_v, inp_dir, at};
|
use crate::dsp::{at, denorm, denorm_offs, inp, out}; //, inp, denorm, denorm_v, inp_dir, at};
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::{cubic_interpolate, Trigger};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_sampl_dir {
|
macro_rules! fa_sampl_dir {
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
// Copyright by Andrew Belt, 2021
|
// Copyright by Andrew Belt, 2021
|
||||||
|
|
||||||
//use super::helpers::{sqrt4_to_pow4, TrigSignal, Trigger};
|
//use super::helpers::{sqrt4_to_pow4, TrigSignal, Trigger};
|
||||||
use synfx_dsp::CustomTrigger;
|
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::SCOPE_SAMPLES;
|
use crate::nodes::SCOPE_SAMPLES;
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
use crate::ScopeHandle;
|
use crate::ScopeHandle;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use synfx_dsp::CustomTrigger;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_scope_tsrc {
|
macro_rules! fa_scope_tsrc {
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
use synfx_dsp::{
|
use synfx_dsp::{
|
||||||
process_1pole_highpass, process_1pole_lowpass, process_1pole_tpt_highpass,
|
process_1pole_highpass, process_1pole_lowpass, process_1pole_tpt_highpass,
|
||||||
process_1pole_tpt_lowpass, process_hal_chamberlin_svf, process_simper_svf,
|
process_1pole_tpt_lowpass, process_hal_chamberlin_svf, process_simper_svf,
|
||||||
process_stilson_moog,
|
process_stilson_moog,
|
||||||
};
|
};
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_sfilter_type {
|
macro_rules! fa_sfilter_type {
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::fast_sin;
|
|
||||||
use crate::dsp::{
|
use crate::dsp::{
|
||||||
denorm_offs, inp, out, DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
denorm_offs, inp, out, DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
||||||
};
|
};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::fast_sin;
|
||||||
|
|
||||||
/// A sine oscillator
|
/// A sine oscillator
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::TrigSignal;
|
|
||||||
use crate::dsp::{
|
use crate::dsp::{
|
||||||
DspNode, GraphAtomData, GraphFun, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
DspNode, GraphAtomData, GraphFun, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
||||||
};
|
};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::TrigSignal;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_test_s {
|
macro_rules! fa_test_s {
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::{Trigger, TriggerPhaseClock};
|
|
||||||
use crate::dsp::tracker::TrackerBackend;
|
use crate::dsp::tracker::TrackerBackend;
|
||||||
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
use crate::dsp::{DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::{Trigger, TriggerPhaseClock};
|
||||||
|
|
||||||
use crate::dsp::MAX_BLOCK_SIZE;
|
use crate::dsp::MAX_BLOCK_SIZE;
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::{TriSawLFO, Trigger};
|
|
||||||
use crate::dsp::{
|
use crate::dsp::{
|
||||||
DspNode, GraphAtomData, GraphFun, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
DspNode, GraphAtomData, GraphFun, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
||||||
};
|
};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::{TriSawLFO, Trigger};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TsLFO {
|
pub struct TsLFO {
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use synfx_dsp::{Oversampling, apply_distortion, VPSOscillator};
|
|
||||||
use crate::dsp::{
|
use crate::dsp::{
|
||||||
DspNode, GraphAtomData, GraphFun, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
DspNode, GraphAtomData, GraphFun, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom,
|
||||||
};
|
};
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
|
use synfx_dsp::{apply_distortion, Oversampling, VPSOscillator};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_vosc_ovrsmpl {
|
macro_rules! fa_vosc_ovrsmpl {
|
||||||
|
|
|
@ -321,8 +321,8 @@ pub mod monitor;
|
||||||
pub mod nodes;
|
pub mod nodes;
|
||||||
pub mod sample_lib;
|
pub mod sample_lib;
|
||||||
pub mod scope_handle;
|
pub mod scope_handle;
|
||||||
pub mod wblockdsp;
|
|
||||||
mod util;
|
mod util;
|
||||||
|
pub mod wblockdsp;
|
||||||
|
|
||||||
pub use cell_dir::CellDir;
|
pub use cell_dir::CellDir;
|
||||||
pub use chain_builder::MatrixCellChain;
|
pub use chain_builder::MatrixCellChain;
|
||||||
|
|
|
@ -8,9 +8,9 @@ use crate::matrix_repr::*;
|
||||||
pub use crate::monitor::MON_SIG_CNT;
|
pub use crate::monitor::MON_SIG_CNT;
|
||||||
pub use crate::nodes::MinMaxMonitorSamples;
|
pub use crate::nodes::MinMaxMonitorSamples;
|
||||||
use crate::nodes::{NodeConfigurator, NodeGraphOrdering, NodeProg, MAX_ALLOCATED_NODES};
|
use crate::nodes::{NodeConfigurator, NodeGraphOrdering, NodeProg, MAX_ALLOCATED_NODES};
|
||||||
|
use crate::wblockdsp::{BlkJITCompileError, BlockFun, BlockFunSnapshot};
|
||||||
pub use crate::CellDir;
|
pub use crate::CellDir;
|
||||||
use crate::ScopeHandle;
|
use crate::ScopeHandle;
|
||||||
use crate::wblockdsp::{BlockFun, BlockFunSnapshot, BlkJITCompileError};
|
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use crate::dsp::{NodeId, ParamId, SAtom};
|
use crate::dsp::{NodeId, ParamId, SAtom};
|
||||||
use serde_json::{json, Value};
|
|
||||||
use crate::wblockdsp::BlockFunSnapshot;
|
use crate::wblockdsp::BlockFunSnapshot;
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct CellRepr {
|
pub struct CellRepr {
|
||||||
|
|
|
@ -6,15 +6,15 @@ use super::{
|
||||||
FeedbackFilter, GraphMessage, NodeOp, NodeProg, MAX_ALLOCATED_NODES, MAX_AVAIL_CODE_ENGINES,
|
FeedbackFilter, GraphMessage, NodeOp, NodeProg, MAX_ALLOCATED_NODES, MAX_AVAIL_CODE_ENGINES,
|
||||||
MAX_AVAIL_TRACKERS, MAX_INPUTS, MAX_SCOPES, UNUSED_MONITOR_IDX,
|
MAX_AVAIL_TRACKERS, MAX_INPUTS, MAX_SCOPES, UNUSED_MONITOR_IDX,
|
||||||
};
|
};
|
||||||
use crate::wblockdsp::*;
|
|
||||||
use crate::dsp::tracker::{PatternData, Tracker};
|
use crate::dsp::tracker::{PatternData, Tracker};
|
||||||
use crate::dsp::{node_factory, Node, NodeId, NodeInfo, ParamId, SAtom};
|
use crate::dsp::{node_factory, Node, NodeId, NodeInfo, ParamId, SAtom};
|
||||||
use crate::monitor::{new_monitor_processor, MinMaxMonitorSamples, Monitor, MON_SIG_CNT};
|
use crate::monitor::{new_monitor_processor, MinMaxMonitorSamples, Monitor, MON_SIG_CNT};
|
||||||
use crate::nodes::drop_thread::DropThread;
|
use crate::nodes::drop_thread::DropThread;
|
||||||
#[cfg(feature = "synfx-dsp-jit")]
|
use crate::wblockdsp::*;
|
||||||
use synfx_dsp_jit::engine::CodeEngine;
|
|
||||||
use crate::SampleLibrary;
|
use crate::SampleLibrary;
|
||||||
use crate::ScopeHandle;
|
use crate::ScopeHandle;
|
||||||
|
#[cfg(feature = "synfx-dsp-jit")]
|
||||||
|
use synfx_dsp_jit::engine::CodeEngine;
|
||||||
|
|
||||||
use ringbuf::{Producer, RingBuffer};
|
use ringbuf::{Producer, RingBuffer};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
|
@ -210,7 +210,7 @@ pub struct Block2JITCompiler {
|
||||||
|
|
||||||
#[cfg(not(feature = "synfx-dsp-jit"))]
|
#[cfg(not(feature = "synfx-dsp-jit"))]
|
||||||
pub enum ASTNode {
|
pub enum ASTNode {
|
||||||
NoSynfxDSPJit
|
NoSynfxDSPJit,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block2JITCompiler {
|
impl Block2JITCompiler {
|
||||||
|
|
|
@ -208,39 +208,42 @@ pub fn setup_hxdsp_block_language(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dsp_lib.borrow().for_each(|node_type| -> Result<(), ()> {
|
dsp_lib
|
||||||
let max_ports = node_type.input_count().max(node_type.output_count());
|
.borrow()
|
||||||
let is_stateful = node_type.is_stateful();
|
.for_each(|node_type| -> Result<(), ()> {
|
||||||
|
let max_ports = node_type.input_count().max(node_type.output_count());
|
||||||
|
let is_stateful = node_type.is_stateful();
|
||||||
|
|
||||||
let mut inputs = vec![];
|
let mut inputs = vec![];
|
||||||
let mut outputs = vec![];
|
let mut outputs = vec![];
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while let Some(name) = node_type.input_names(i) {
|
while let Some(name) = node_type.input_names(i) {
|
||||||
inputs.push(Some(name[0..(name.len().min(2))].to_string()));
|
inputs.push(Some(name[0..(name.len().min(2))].to_string()));
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while let Some(name) = node_type.output_names(i) {
|
while let Some(name) = node_type.output_names(i) {
|
||||||
outputs.push(Some(name[0..(name.len().min(2))].to_string()));
|
outputs.push(Some(name[0..(name.len().min(2))].to_string()));
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
lang.define(BlockType {
|
lang.define(BlockType {
|
||||||
category: if is_stateful { "nodes".to_string() } else { "functions".to_string() },
|
category: if is_stateful { "nodes".to_string() } else { "functions".to_string() },
|
||||||
name: node_type.name().to_string(),
|
name: node_type.name().to_string(),
|
||||||
rows: max_ports,
|
rows: max_ports,
|
||||||
area_count: 0,
|
area_count: 0,
|
||||||
user_input: BlockUserInput::None,
|
user_input: BlockUserInput::None,
|
||||||
description: node_type.documentation().to_string(),
|
description: node_type.documentation().to_string(),
|
||||||
color: if is_stateful { 8 } else { 16 },
|
color: if is_stateful { 8 } else { 16 },
|
||||||
inputs,
|
inputs,
|
||||||
outputs,
|
outputs,
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}).expect("seriously no error here");
|
})
|
||||||
|
.expect("seriously no error here");
|
||||||
|
|
||||||
lang.define_identifier("in1");
|
lang.define_identifier("in1");
|
||||||
lang.define_identifier("in2");
|
lang.define_identifier("in2");
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
mod compiler;
|
||||||
mod definition;
|
mod definition;
|
||||||
mod language;
|
mod language;
|
||||||
mod compiler;
|
|
||||||
|
|
||||||
|
pub use compiler::*;
|
||||||
pub use definition::*;
|
pub use definition::*;
|
||||||
pub use language::*;
|
pub use language::*;
|
||||||
pub use compiler::*;
|
|
||||||
|
|
133
tests/node_formant.rs
Normal file
133
tests/node_formant.rs
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
mod common;
|
||||||
|
use common::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_normalized_if_freq_lower_than_formant_freq() {
|
||||||
|
let (node_conf, mut node_exec) = new_node_engine();
|
||||||
|
|
||||||
|
let mut matrix = Matrix::new(node_conf, 3, 3);
|
||||||
|
|
||||||
|
let mut chain = MatrixCellChain::new(CellDir::B);
|
||||||
|
chain.node_out("formant", "sig").node_inp("out", "ch1").place(&mut matrix, 0, 0).unwrap();
|
||||||
|
|
||||||
|
matrix.sync().unwrap();
|
||||||
|
|
||||||
|
let formant = NodeId::Formant(0);
|
||||||
|
|
||||||
|
// params
|
||||||
|
let freq_p = formant.inp_param("freq").unwrap();
|
||||||
|
let form_p = formant.inp_param("form").unwrap();
|
||||||
|
let atk_p = formant.inp_param("atk").unwrap();
|
||||||
|
let dcy_p = formant.inp_param("dcy").unwrap();
|
||||||
|
|
||||||
|
// set params to reasonable values
|
||||||
|
matrix.set_param(freq_p, SAtom::param(-0.2));
|
||||||
|
matrix.set_param(form_p, SAtom::param(0.0));
|
||||||
|
matrix.set_param(atk_p, SAtom::param(0.2));
|
||||||
|
matrix.set_param(dcy_p, SAtom::param(-0.2));
|
||||||
|
|
||||||
|
// run
|
||||||
|
let res = run_for_ms(&mut node_exec, 100.0);
|
||||||
|
|
||||||
|
// and check it's normalized
|
||||||
|
let max = res.0.iter().fold(0.0 as f32, |acc, x| acc.max(*x));
|
||||||
|
let min = res.0.iter().fold(0.0 as f32, |acc, x| acc.min(*x));
|
||||||
|
assert!(max > 0.8 && max < 1.01 && min < -0.8 && min > -1.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_no_dc_bias_at_formant_freq_lower_than_freq() {
|
||||||
|
let (node_conf, mut node_exec) = new_node_engine();
|
||||||
|
|
||||||
|
let mut matrix = Matrix::new(node_conf, 3, 3);
|
||||||
|
|
||||||
|
let mut chain = MatrixCellChain::new(CellDir::B);
|
||||||
|
chain.node_out("formant", "sig").node_inp("out", "ch1").place(&mut matrix, 0, 0).unwrap();
|
||||||
|
|
||||||
|
matrix.sync().unwrap();
|
||||||
|
|
||||||
|
let formant = NodeId::Formant(0);
|
||||||
|
|
||||||
|
// params
|
||||||
|
let freq_p = formant.inp_param("freq").unwrap();
|
||||||
|
let form_p = formant.inp_param("form").unwrap();
|
||||||
|
let atk_p = formant.inp_param("atk").unwrap();
|
||||||
|
let dcy_p = formant.inp_param("dcy").unwrap();
|
||||||
|
|
||||||
|
// set params to reasonable values
|
||||||
|
matrix.set_param(freq_p, SAtom::param(0.0));
|
||||||
|
matrix.set_param(form_p, SAtom::param(-0.2));
|
||||||
|
matrix.set_param(atk_p, SAtom::param(0.2));
|
||||||
|
matrix.set_param(dcy_p, SAtom::param(-0.2));
|
||||||
|
|
||||||
|
// run
|
||||||
|
let res = run_for_ms(&mut node_exec, 100.0);
|
||||||
|
|
||||||
|
// average should remain at ~0
|
||||||
|
let sum = res.0.iter().sum::<f32>();
|
||||||
|
let avg = sum / res.0.len() as f32;
|
||||||
|
|
||||||
|
assert!(avg > -0.05 && avg < 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_no_nan() {
|
||||||
|
let (node_conf, mut node_exec) = new_node_engine();
|
||||||
|
|
||||||
|
let mut matrix = Matrix::new(node_conf, 3, 3);
|
||||||
|
|
||||||
|
let mut chain = MatrixCellChain::new(CellDir::B);
|
||||||
|
chain.node_out("formant", "sig").node_inp("out", "ch1").place(&mut matrix, 0, 0).unwrap();
|
||||||
|
|
||||||
|
matrix.sync().unwrap();
|
||||||
|
|
||||||
|
let formant = NodeId::Formant(0);
|
||||||
|
|
||||||
|
// params
|
||||||
|
let freq_p = formant.inp_param("freq").unwrap();
|
||||||
|
let form_p = formant.inp_param("form").unwrap();
|
||||||
|
let atk_p = formant.inp_param("atk").unwrap();
|
||||||
|
let dcy_p = formant.inp_param("dcy").unwrap();
|
||||||
|
|
||||||
|
// set params to non-reasonable values here
|
||||||
|
// base freq 0
|
||||||
|
matrix.set_param(freq_p, SAtom::param(-1.0));
|
||||||
|
matrix.set_param(form_p, SAtom::param(0.0));
|
||||||
|
matrix.set_param(atk_p, SAtom::param(0.2));
|
||||||
|
matrix.set_param(dcy_p, SAtom::param(-0.2));
|
||||||
|
|
||||||
|
// run
|
||||||
|
let res = run_for_ms(&mut node_exec, 100.0);
|
||||||
|
|
||||||
|
// and check there's no NaN
|
||||||
|
assert!(res.0.iter().all(|x| !x.is_nan()));
|
||||||
|
|
||||||
|
// set params to non-reasonable values here
|
||||||
|
// base freq attack freq 0
|
||||||
|
matrix.set_param(freq_p, SAtom::param(-0.2));
|
||||||
|
matrix.set_param(form_p, SAtom::param(0.0));
|
||||||
|
matrix.set_param(atk_p, SAtom::param(-1.0));
|
||||||
|
matrix.set_param(dcy_p, SAtom::param(-0.2));
|
||||||
|
|
||||||
|
// run
|
||||||
|
let res = run_for_ms(&mut node_exec, 100.0);
|
||||||
|
|
||||||
|
// and check there's no NaN
|
||||||
|
assert!(res.0.iter().all(|x| !x.is_nan()));
|
||||||
|
|
||||||
|
// set params to non-reasonable values here
|
||||||
|
// decay freq freq 0
|
||||||
|
matrix.set_param(freq_p, SAtom::param(-0.2));
|
||||||
|
matrix.set_param(form_p, SAtom::param(0.0));
|
||||||
|
matrix.set_param(atk_p, SAtom::param(0.2));
|
||||||
|
matrix.set_param(dcy_p, SAtom::param(-1.0));
|
||||||
|
|
||||||
|
// run
|
||||||
|
let res = run_for_ms(&mut node_exec, 100.0);
|
||||||
|
|
||||||
|
// and check there's no NaN
|
||||||
|
assert!(res.0.iter().all(|x| !x.is_nan()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_formant_freq() {}
|
Loading…
Reference in a new issue