Implemented the real quantizer node now.

This commit is contained in:
Weird Constructor 2021-08-28 19:56:08 +02:00
parent 204c415c06
commit 172138bc19
4 changed files with 99 additions and 45 deletions

View file

@ -2158,36 +2158,6 @@ impl Quantizer {
self.setup_lookup_table(); self.setup_lookup_table();
} }
// mk_pitch_lookup_table = {!enabled = _;
// !any = $f;
// iter n enabled { if n { .any = $t } };
//
// !tbl = $[];
//
// iter i 0 => 24 {
// !minDistNote = 0;
// !minDist = 10000000000;
//
// iter note -12 => 25 {
// !dist = std:num:abs[ (i + 1) / 2 - note ];
//
// !idx = eucMod note 12;
// if any &and not[enabled.(idx)] {
// next[];
// };
// std:displayln "DIST" (i + 1) / 2 note idx "=>" dist;
// if dist < minDist {
// .minDistNote = idx;
// .minDist = dist;
// } { break[] };
// };
//
// tbl.(i) = minDistNote;
// };
//
// tbl
//};
//
#[inline] #[inline]
fn setup_lookup_table(&mut self) { fn setup_lookup_table(&mut self) {
let mask = self.old_mask; let mask = self.old_mask;
@ -2210,10 +2180,10 @@ impl Quantizer {
continue; continue;
} }
println!("I={:3} NOTE={:3} (IDX={:3} => bitset {}) DIST={:3}", //d// println!("I={:3} NOTE={:3} (IDX={:3} => bitset {}) DIST={:3}",
i, note, note_idx, //d// i, note, note_idx,
if (mask & (0x1 << ((note_idx + 9) % 12))) > 0x0 { 1 } else { 0 }, //d// if (mask & (0x1 << ((note_idx + 9) % 12))) > 0x0 { 1 } else { 0 },
dist); //d// dist);
if dist < min_dist { if dist < min_dist {
min_d_note_idx = note; min_d_note_idx = note;
@ -2232,16 +2202,6 @@ impl Quantizer {
//d// println!("TBL: {:?}", self.lkup_tbl); //d// println!("TBL: {:?}", self.lkup_tbl);
} }
//# float pitch = inputs[PITCH_INPUT].getVoltage(c);
//# int range = std::floor(pitch * 24); // 1.1 => 26
//# int octave = eucDiv(range, 24); // 26 => 1
//# range -= octave * 24; // 26 => 2
//# int note = ranges[range] + octave * 12;
//# playingNotes[eucMod(note, 12)] = true;
//# pitch = float(note) / 12;
//# outputs[PITCH_OUTPUT].setVoltage(pitch, c);
#[inline] #[inline]
pub fn process(&self, inp: f32) -> f32 { pub fn process(&self, inp: f32) -> f32 {
let note_num = (inp * 240.0).round() as i64; let note_num = (inp * 240.0).round() as i64;

View file

@ -50,6 +50,8 @@ mod node_rndwk;
mod node_mux9; mod node_mux9;
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
mod node_cqnt; mod node_cqnt;
#[allow(non_upper_case_globals)]
mod node_quant;
pub mod biquad; pub mod biquad;
pub mod tracker; pub mod tracker;
@ -91,6 +93,7 @@ use crate::fa_mux9_in_cnt;
use crate::fa_cqnt; use crate::fa_cqnt;
use crate::fa_cqnt_omin; use crate::fa_cqnt_omin;
use crate::fa_cqnt_omax; use crate::fa_cqnt_omax;
use crate::fa_quant;
use node_amp::Amp; use node_amp::Amp;
use node_sin::Sin; use node_sin::Sin;
@ -117,6 +120,7 @@ use node_pverb::PVerb;
use node_rndwk::RndWk; use node_rndwk::RndWk;
use node_mux9::Mux9; use node_mux9::Mux9;
use node_cqnt::CQnt; use node_cqnt::CQnt;
use node_quant::Quant;
pub const MIDI_MAX_FREQ : f32 = 13289.75; pub const MIDI_MAX_FREQ : f32 = 13289.75;
@ -739,6 +743,11 @@ macro_rules! node_list {
(6 max n_id d_id r_s f_def stp_d -1.0, 1.0, 1.0) (6 max n_id d_id r_s f_def stp_d -1.0, 1.0, 1.0)
{7 0 clip setting(0) fa_map_clip 0 1} {7 0 clip setting(0) fa_map_clip 0 1}
[0 sig], [0 sig],
quant => Quant UIType::Generic UICategory::CV
(0 freq n_pit d_pit r_fq f_freq stp_d -1.0, 0.5647131, 440.0)
(1 oct n_id d_id r_s f_def stp_d -1.0, 1.0, 0.0)
{2 0 keys setting(0) fa_quant 0 0}
[0 sig],
cqnt => CQnt UIType::Generic UICategory::CV cqnt => CQnt UIType::Generic UICategory::CV
(0 inp n_id d_id r_id f_def stp_d 0.0, 1.0, 0.0) (0 inp n_id d_id r_id f_def stp_d 0.0, 1.0, 0.0)
(1 oct n_id d_id r_s f_def stp_d -1.0, 1.0, 0.0) (1 oct n_id d_id r_s f_def stp_d -1.0, 1.0, 0.0)

View file

@ -39,7 +39,7 @@ macro_rules! fa_cqnt_omax { ($formatter: expr, $v: expr, $denorm_v: expr) => { {
write!($formatter, "{}", s) write!($formatter, "{}", s)
} } } } } }
/// A 9 channel signal multiplexer /// A control signal to pitch quantizer/converter
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct CQnt { pub struct CQnt {
quant: Box<CtrlPitchQuantizer>, quant: Box<CtrlPitchQuantizer>,

85
src/dsp/node_quant.rs Normal file
View file

@ -0,0 +1,85 @@
// 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::Quantizer;
#[macro_export]
macro_rules! fa_quant { ($formatter: expr, $v: expr, $denorm_v: expr) => { {
write!($formatter, "?")
} } }
/// A pitch quantizer
#[derive(Debug, Clone)]
pub struct Quant {
quant: Box<Quantizer>,
}
impl Quant {
pub fn new(_nid: &NodeId) -> Self {
Self {
quant: Box::new(Quantizer::new()),
}
}
pub const freq : &'static str =
"Quant freq\n\nRange: (0..1)";
pub const oct : &'static str =
"Quant oct\n\nRange: (-1..1)";
pub const sig : &'static str =
"Quant sig\n\nRange: (-1..1)";
pub const keys : &'static str =
"Quant keys\n";
pub const DESC : &'static str =
r#"Pitch Quantizer
This is a simple quantizer, that snaps a pitch signal on 'freq' to the closest selected notes within their octave.
"#;
pub const HELP : &'static str =
r#"Quant - A pitch quantizer
This is a simple quantizer, that snaps a pitch signal on 'freq' to the
closest selected notes within their octave.
If you sweep along pitches you will notice that notes that are closer together
are travelled across faster. That means the notes are not evenly distributed
across the pitch input. If you want a more evenly distributed pitch selection
please see also the 'CQnt' node.
"#;
}
impl DspNode for Quant {
fn outputs() -> usize { 1 }
fn set_sample_rate(&mut self, _srate: f32) { }
fn reset(&mut self) { }
#[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::{at, out, inp, denorm};
let freq = inp::Quant::freq(inputs);
let oct = inp::Quant::oct(inputs);
let keys = at::Quant::keys(atoms);
let out = out::Quant::sig(outputs);
self.quant.set_keys(keys.i());
// let mut last_key = 0;
for frame in 0..ctx.nframes() {
let pitch = self.quant.process(freq.read(frame));
out.write(frame, pitch + denorm::Quant::oct(oct, frame));
}
// let last_pitch = self.quant.last_key_pitch();
// ctx_vals[1].set(last_pitch * 10.0 + 0.0001);
// ctx_vals[0].set((last_pitch * 10.0 - 0.5) * 2.0);
}
}