Added 'det' detune parameter to FormFM oscillator
This commit is contained in:
parent
2e2424d60a
commit
1a1512a032
4 changed files with 45 additions and 7 deletions
|
@ -1527,9 +1527,10 @@ macro_rules! node_list {
|
||||||
[0 sig],
|
[0 sig],
|
||||||
formfm => FormFM UIType::Generic UICategory::Osc
|
formfm => FormFM UIType::Generic UICategory::Osc
|
||||||
(0 freq n_pit d_pit r_fq f_freq stp_d -1.0, 0.5647131, 440.0)
|
(0 freq n_pit d_pit r_fq f_freq stp_d -1.0, 0.5647131, 440.0)
|
||||||
(1 form n_pit d_pit r_fq f_freq stp_d -1.0, 0.5647131, 440.0)
|
(1 det n_det d_det r_det f_det stp_f -0.2, 0.2, 0.0)
|
||||||
(2 side n_id d_id r_id f_def stp_d 0.0, 1.0, 0.2)
|
(2 form n_pit d_pit r_fq f_freq stp_d -1.0, 0.5647131, 440.0)
|
||||||
(3 peak n_id d_id r_id f_def stp_d 0.0, 1.0, 0.4)
|
(3 side n_id d_id r_id f_def stp_d 0.0, 1.0, 0.2)
|
||||||
|
(4 peak n_id d_id r_id f_def stp_d 0.0, 1.0, 0.4)
|
||||||
[0 sig],
|
[0 sig],
|
||||||
sfilter => SFilter UIType::Generic UICategory::Signal
|
sfilter => SFilter UIType::Generic UICategory::Signal
|
||||||
(0 inp n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)
|
(0 inp n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)
|
||||||
|
|
|
@ -16,7 +16,8 @@ impl FormFM {
|
||||||
pub fn new(_nid: &NodeId) -> Self {
|
pub fn new(_nid: &NodeId) -> Self {
|
||||||
Self { inv_sample_rate: 1.0 / 44100.0, phase: 0.0 }
|
Self { inv_sample_rate: 1.0 / 44100.0, phase: 0.0 }
|
||||||
}
|
}
|
||||||
pub const freq: &'static str = "Formant freq\nBase frequency to oscilate at\n";
|
pub const freq: &'static str = "Formant freq\nBase frequency to oscillate at\n";
|
||||||
|
pub const det: &'static str = "Formant det\nDetune the oscillator in semitones and cents.\n";
|
||||||
pub const form: &'static str = "Formant form\nFrequency of the formant\nThis affects how much lower or higher tones the sound has.";
|
pub const form: &'static str = "Formant form\nFrequency of the formant\nThis affects how much lower or higher tones the sound has.";
|
||||||
pub const side: &'static str =
|
pub const side: &'static str =
|
||||||
"Formant side\nWhich side the peak of the wave is. Values more towards 0.0 or 1.0 make the base frequency more pronounced";
|
"Formant side\nWhich side the peak of the wave is. Values more towards 0.0 or 1.0 make the base frequency more pronounced";
|
||||||
|
@ -74,9 +75,10 @@ impl DspNode for FormFM {
|
||||||
outputs: &mut [ProcBuf],
|
outputs: &mut [ProcBuf],
|
||||||
_ctx_vals: LedPhaseVals,
|
_ctx_vals: LedPhaseVals,
|
||||||
) {
|
) {
|
||||||
use crate::dsp::{denorm, inp, out};
|
use crate::dsp::{denorm, denorm_offs, inp, out};
|
||||||
|
|
||||||
let base_freq = inp::FormFM::freq(inputs);
|
let base_freq = inp::FormFM::freq(inputs);
|
||||||
|
let det = inp::FormFM::det(inputs);
|
||||||
let formant_freq = inp::FormFM::form(inputs);
|
let formant_freq = inp::FormFM::form(inputs);
|
||||||
let side_val = inp::FormFM::side(inputs);
|
let side_val = inp::FormFM::side(inputs);
|
||||||
let peak_val = inp::FormFM::peak(inputs);
|
let peak_val = inp::FormFM::peak(inputs);
|
||||||
|
@ -84,7 +86,7 @@ impl DspNode for FormFM {
|
||||||
|
|
||||||
for frame in 0..ctx.nframes() {
|
for frame in 0..ctx.nframes() {
|
||||||
// get the inputs
|
// get the inputs
|
||||||
let base_freq = denorm::FormFM::freq(base_freq, frame);
|
let base_freq = denorm_offs::FormFM::freq(base_freq, det.read(frame), frame);
|
||||||
let formant_freq = denorm::FormFM::form(formant_freq, frame);
|
let formant_freq = denorm::FormFM::form(formant_freq, frame);
|
||||||
let side_val = denorm::FormFM::side(side_val, frame).min(1.0 - 1e-6).max(1e-6);
|
let side_val = denorm::FormFM::side(side_val, frame).min(1.0 - 1e-6).max(1e-6);
|
||||||
let peak_val = denorm::FormFM::peak(peak_val, frame);
|
let peak_val = denorm::FormFM::peak(peak_val, frame);
|
||||||
|
|
|
@ -88,7 +88,7 @@ impl DspNode for Sin {
|
||||||
|
|
||||||
let mut last_val = 0.0;
|
let mut last_val = 0.0;
|
||||||
for frame in 0..ctx.nframes() {
|
for frame in 0..ctx.nframes() {
|
||||||
let freq = denorm_offs::Sampl::freq(freq, det.read(frame), frame);
|
let freq = denorm_offs::Sin::freq(freq, det.read(frame), frame);
|
||||||
|
|
||||||
last_val = fast_sin(self.phase * TWOPI);
|
last_val = fast_sin(self.phase * TWOPI);
|
||||||
o.write(frame, last_val);
|
o.write(frame, last_val);
|
||||||
|
|
|
@ -162,3 +162,38 @@ fn check_formant_freq() {
|
||||||
let fft = run_and_get_avg_fft4096_now(&mut node_exec, 100);
|
let fft = run_and_get_avg_fft4096_now(&mut node_exec, 100);
|
||||||
assert_eq!(fft, vec![(323, 106), (334, 131), (431, 430), (441, 708), (452, 288), (549, 140)]);
|
assert_eq!(fft, vec![(323, 106), (334, 131), (431, 430), (441, 708), (452, 288), (549, 140)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_formant_freq_det() {
|
||||||
|
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("formfm", "sig")
|
||||||
|
.set_denorm("det", 0.1)
|
||||||
|
.node_inp("out", "ch1")
|
||||||
|
.place(&mut matrix, 0, 0)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
matrix.sync().unwrap();
|
||||||
|
|
||||||
|
let formant = NodeId::FormFM(0);
|
||||||
|
|
||||||
|
// params
|
||||||
|
let freq_p = formant.inp_param("freq").unwrap();
|
||||||
|
let form_p = formant.inp_param("form").unwrap();
|
||||||
|
let side_p = formant.inp_param("side").unwrap();
|
||||||
|
let peak_p = formant.inp_param("peak").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(side_p, SAtom::param(0.2));
|
||||||
|
matrix.set_param(peak_p, SAtom::param(0.4));
|
||||||
|
|
||||||
|
// run
|
||||||
|
let fft = run_and_get_avg_fft4096_now(&mut node_exec, 100);
|
||||||
|
assert_eq!(fft, vec![(334, 146), (431, 297), (441, 696), (452, 406), (549, 127), (560, 107)]);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue