Initialize all oscillators with different phases and adjust the corresponding tests accordingly.

This commit is contained in:
Weird Constructor 2021-07-25 22:49:33 +02:00
parent 76ab78d565
commit 25aaf5ba7d
6 changed files with 42 additions and 26 deletions

View file

@ -963,6 +963,23 @@ macro_rules! make_node_info_enum {
} }
} }
/// Consistently initialize the phase for oscillators.
/// This does some fixed phase offset for the first 3
/// instances, which is usually relied on by the automated
/// tests.
#[inline]
pub fn init_phase(&self) -> f32 {
// The first 3 instances get a fixed predefined phase to
// not mess up the automated tests so easily.
match self.instance() {
0 => 0.0,
1 => 0.05,
2 => 0.1,
// 0.25 just to protect against sine cancellation
_ => crate::dsp::helpers::rand_01() * 0.25
}
}
/// This maps the atom index of the node to the absolute /// This maps the atom index of the node to the absolute
/// ParamId in the GUI (and in the [crate::matrix::Matrix]). /// ParamId in the GUI (and in the [crate::matrix::Matrix]).
/// The Atom/Param duality is a bit weird because they share /// The Atom/Param duality is a bit weird because they share

View file

@ -4,7 +4,7 @@
use crate::nodes::{NodeAudioContext, NodeExecContext}; use crate::nodes::{NodeAudioContext, NodeExecContext};
use crate::dsp::{NodeId, SAtom, ProcBuf, DspNode, LedPhaseVals, NodeContext}; use crate::dsp::{NodeId, SAtom, ProcBuf, DspNode, LedPhaseVals, NodeContext};
use crate::dsp::helpers::{rand_01, PolyBlepOscillator}; use crate::dsp::helpers::PolyBlepOscillator;
#[macro_export] #[macro_export]
macro_rules! fa_bosc_wtype { ($formatter: expr, $v: expr, $denorm_v: expr) => { { macro_rules! fa_bosc_wtype { ($formatter: expr, $v: expr, $denorm_v: expr) => { {
@ -28,13 +28,7 @@ pub struct BOsc {
impl BOsc { impl BOsc {
pub fn new(nid: &NodeId) -> Self { pub fn new(nid: &NodeId) -> Self {
let init_phase = let init_phase = nid.init_phase();
if nid.instance() > 0 {
// 0.5 just to protect against sine cancellation
rand_01() * 0.5
} else {
0.0
};
Self { Self {
osc: PolyBlepOscillator::new(init_phase), osc: PolyBlepOscillator::new(init_phase),

View file

@ -16,15 +16,20 @@ pub struct Sin {
srate: f32, srate: f32,
/// Oscillator phase /// Oscillator phase
phase: f32, phase: f32,
/// Initial phase offset
init_phase: f32,
} }
const TWOPI : f32 = 2.0 * std::f32::consts::PI; const TWOPI : f32 = 2.0 * std::f32::consts::PI;
impl Sin { impl Sin {
pub fn new(_nid: &NodeId) -> Self { pub fn new(nid: &NodeId) -> Self {
let init_phase = nid.init_phase();
Self { Self {
srate: 44100.0, srate: 44100.0,
phase: 0.0, phase: init_phase,
init_phase,
} }
} }
pub const freq : &'static str = pub const freq : &'static str =
@ -70,7 +75,7 @@ impl DspNode for Sin {
} }
fn reset(&mut self) { fn reset(&mut self) {
self.phase = 0.0; self.phase = self.init_phase;
} }
#[inline] #[inline]

View file

@ -45,8 +45,8 @@ fn check_matrix_sine() {
let sin_led_val = matrix.led_value_for(&sin); let sin_led_val = matrix.led_value_for(&sin);
let out_led_val = matrix.led_value_for(&out); let out_led_val = matrix.led_value_for(&out);
assert_float_eq!(sin_led_val, -0.057622954); assert_float_eq!(sin_led_val, 0.54018);
assert_float_eq!(out_led_val, -0.057622954); assert_float_eq!(out_led_val, 0.54018);
} }
#[test] #[test]
@ -94,7 +94,7 @@ fn check_sine_pitch_change() {
let (node_conf, mut node_exec) = new_node_engine(); let (node_conf, mut node_exec) = new_node_engine();
let mut matrix = Matrix::new(node_conf, 3, 3); let mut matrix = Matrix::new(node_conf, 3, 3);
let sin = NodeId::Sin(2); let sin = NodeId::Sin(0);
let out = NodeId::Out(0); let out = NodeId::Out(0);
matrix.place(0, 0, Cell::empty(sin) matrix.place(0, 0, Cell::empty(sin)
.out(None, sin.out("sig"), None)); .out(None, sin.out("sig"), None));
@ -255,7 +255,7 @@ fn check_matrix_monitor() {
} }
let rms_mimax = calc_rms_mimax_each_ms(&out_l[..], 50.0); let rms_mimax = calc_rms_mimax_each_ms(&out_l[..], 50.0);
assert_float_eq!(rms_mimax[0].0, 0.5013241); assert_float_eq!(rms_mimax[0].0, 0.49901);
// let ta = std::time::Instant::now(); // let ta = std::time::Instant::now();
@ -1082,10 +1082,10 @@ fn check_matrix_node_feedback() {
// The frequency will be established a bit later because // The frequency will be established a bit later because
// the parameter setting of 880 Hz will be smoothed: // the parameter setting of 880 Hz will be smoothed:
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.6889244, 0.9872897, 0.40561166, -0.5643036, -0.99751425, 0.8791775, 0.8898413, 0.10330327, -0.79178804, -0.92698133,
-0.42060927, 0.6112674, 0.979101, 0.21974884, -0.81355125, -0.11967586, 0.8259115, 0.86836, -0.09246742, -0.9534301,
-0.83687085, 0.23462467, 0.9970811, 0.35165882, -0.8186541, -0.62676203, 0.5235326, 0.9718173, 0.04517236, -0.9560416,
-0.7396998, 0.5222105, 0.9234876, -0.2683919, -0.983062 ]); -0.49554884, 0.7601789, 0.75973713, -0.5529301, -0.8783003 ]);
// Let the frequency settle... // Let the frequency settle...
run_for_ms(&mut node_exec, 80.0); run_for_ms(&mut node_exec, 80.0);

View file

@ -42,7 +42,7 @@ fn check_param_mod_amt_with_input() {
sin.inp_param("freq").unwrap(), Some(0.2)).unwrap(); sin.inp_param("freq").unwrap(), Some(0.2)).unwrap();
let rms = run_and_get_first_rms_mimax(&mut node_exec, 50.0); let rms = run_and_get_first_rms_mimax(&mut node_exec, 50.0);
assert_rmsmima!(rms, (0.4992, -1.0, 1.0)); assert_rmsmima!(rms, (0.48997, -1.0, 1.0));
} }
#[test] #[test]

View file

@ -83,7 +83,7 @@ fn check_node_delay_time_mod() {
let (node_conf, mut node_exec) = new_node_engine(); let (node_conf, mut node_exec) = new_node_engine();
let mut matrix = Matrix::new(node_conf, 4, 4); let mut matrix = Matrix::new(node_conf, 4, 4);
let sin = NodeId::Sin(0); let sin = NodeId::Sin(1);
let dly = NodeId::Delay(0); let dly = NodeId::Delay(0);
let out = NodeId::Out(0); let out = NodeId::Out(0);
matrix.place(1, 1, Cell::empty(sin) matrix.place(1, 1, Cell::empty(sin)
@ -106,7 +106,7 @@ fn check_node_delay_time_mod() {
assert_eq!(fft[0], (431, 614)); assert_eq!(fft[0], (431, 614));
assert_eq!(fft[1], (441, 1012)); assert_eq!(fft[1], (441, 1012));
let sin2 = NodeId::Sin(1); let sin2 = NodeId::Sin(0);
matrix.place(0, 3, Cell::empty(sin2) matrix.place(0, 3, Cell::empty(sin2)
.out(sin2.out("sig"), None, None)); .out(sin2.out("sig"), None, None));
@ -122,15 +122,15 @@ fn check_node_delay_time_mod() {
let fft = run_and_get_fft4096_now(&mut node_exec, 110); let fft = run_and_get_fft4096_now(&mut node_exec, 110);
// Expect a sine sweep over a // Expect a sine sweep over a
// range of low frequencies: // range of low frequencies:
assert_eq!(fft[0], (108, 111)); assert_eq!(fft[0], (86, 112));
assert_eq!(fft[5], (312, 110)); assert_eq!(fft[5], (237, 112));
assert_eq!(fft[10], (700, 110)); assert_eq!(fft[10], (517, 111));
// Sweep upwards: // Sweep upwards:
run_for_ms(&mut node_exec, 300.0); run_for_ms(&mut node_exec, 300.0);
let fft = run_and_get_fft4096_now(&mut node_exec, 122); let fft = run_and_get_fft4096_now(&mut node_exec, 122);
assert_eq!(fft[0], (2509, 123)); assert_eq!(fft[0], (2509, 123));
assert_eq!(fft[8], (2821, 123)); assert_eq!(fft[7], (2821, 123));
// Sweep at mostly highest point: // Sweep at mostly highest point:
run_for_ms(&mut node_exec, 700.0); run_for_ms(&mut node_exec, 700.0);