implemented basic sample oscillator

This commit is contained in:
Weird Constructor 2021-05-22 09:19:11 +02:00
parent b11743442a
commit 0c3d5e99fa
4 changed files with 70 additions and 8 deletions

View file

@ -8,11 +8,13 @@ use crate::dsp::{SAtom, ProcBuf, DspNode, LedPhaseVals};
/// A simple amplifier
#[derive(Debug, Clone)]
pub struct Sampl {
sample_idx: usize,
}
impl Sampl {
pub fn new() -> Self {
Self {
sample_idx: 0,
}
}
pub const freq : &'static str =
@ -35,15 +37,26 @@ impl DspNode for Sampl {
&mut self, ctx: &mut T, atoms: &[SAtom], _params: &[ProcBuf],
inputs: &[ProcBuf], outputs: &mut [ProcBuf], ctx_vals: LedPhaseVals)
{
use crate::dsp::{out}; //, inp, denorm, denorm_v, inp_dir, at};
use crate::dsp::{out, at, inp, denorm}; //, inp, denorm, denorm_v, inp_dir, at};
// let gain = inp::Amp::gain(inputs);
// let att = inp::Amp::att(inputs);
// let inp = inp::Amp::inp(inputs);
let out = out::Sampl::sig(outputs);
let sample = at::Sampl::sample(atoms);
let freq = inp::Sampl::freq(inputs);
let out = out::Sampl::sig(outputs);
for frame in 0..ctx.nframes() {
out.write(frame, 0.0);
if let SAtom::AudioSample((_, Some(sample_data))) = sample {
let sd_len = sample_data.len() - 1;
for frame in 0..ctx.nframes() {
let speed = denorm::Sampl::freq(freq, frame) / 440.0;
let sd = sample_data[self.sample_idx % sd_len + 1];
out.write(frame, sd);
self.sample_idx += (1.0 * speed).ceil() as usize;
}
} else {
for frame in 0..ctx.nframes() {
out.write(frame, 0.0);
}
}
ctx_vals[0].set(1.0);

View file

@ -12,6 +12,7 @@ use super::{
};
use crate::nodes::drop_thread::DropThread;
use crate::dsp::{NodeId, ParamId, NodeInfo, Node, SAtom, node_factory};
use crate::{SampleLibrary};
use crate::util::AtomicFloat;
use crate::monitor::{
Monitor, MON_SIG_CNT, new_monitor_processor, MinMaxMonitorSamples
@ -142,6 +143,10 @@ pub struct NodeConfigurator {
feedback_filter: FeedbackFilter,
/// Loads and Caches audio samples that are set as parameters
/// for nodes.
sample_lib: SampleLibrary,
/// Contains (automateable) parameters
params: std::collections::HashMap<ParamId, NodeInputParam>,
/// Stores the most recently set parameter values
@ -226,6 +231,7 @@ impl NodeConfigurator {
(NodeConfigurator {
nodes,
shared,
sample_lib: SampleLibrary::new(),
feedback_filter: FeedbackFilter::new(),
output_fb_values: vec![],
output_fb_cons: None,
@ -292,6 +298,13 @@ impl NodeConfigurator {
/// then the value will be remembered until [NodeConfigurator::rebuild_node_ports] is called.
pub fn set_param(&mut self, param: ParamId, at: SAtom) {
if param.is_atom() {
let at =
if let SAtom::AudioSample((path, None)) = at {
self.sample_lib.load(&path).unwrap().clone()
} else {
at
};
self.atom_values.insert(param, at.clone());
if let Some(nparam) = self.atoms.get_mut(&param) {

View file

@ -64,7 +64,9 @@ impl SampleLibrary {
},
hound::SampleFormat::Int => {
for s in rd.samples::<i16>().step_by(channels) {
v.push(s? as f32 / (i16::MAX as f32));
let s = s?;
let s = s as f32 / (i16::MAX as f32);
v.push(s);
}
},
};

View file

@ -1105,3 +1105,37 @@ fn check_matrix_output_feedback() {
assert_float_eq!(fo_amp.1, 0.11627);
}
#[test]
fn check_node_sampl_1() {
let (node_conf, mut node_exec) = new_node_engine();
let mut matrix = Matrix::new(node_conf, 3, 3);
let smpl = NodeId::Sampl(0);
let out = NodeId::Out(0);
matrix.place(0, 0, Cell::empty(smpl)
.out(None, None, smpl.out("sig")));
matrix.place(0, 1, Cell::empty(out)
.input(out.inp("ch1"), None, None));
matrix.sync().unwrap();
let sample_p = smpl.inp_param("sample").unwrap();
let freq_p = smpl.inp_param("freq").unwrap();
matrix.set_param(sample_p, SAtom::audio_unloaded("tests/sample_sin.wav"));
let (rms, min, max) = run_and_get_l_rms_mimax(&mut node_exec, 50.0);
assert_float_eq!(rms, 0.505);
assert_float_eq!(min, -0.9998);
assert_float_eq!(max, 1.0);
let fft = run_and_get_fft4096(&mut node_exec, 800, 0.0);
assert_eq!(fft[0], (441, 940));
matrix.set_param(freq_p, SAtom::param(0.1));
let fft = run_and_get_fft4096(&mut node_exec, 800, 0.0);
assert_eq!(fft[0], (894, 988));
matrix.set_param(freq_p, SAtom::param(-0.1));
let fft = run_and_get_fft4096(&mut node_exec, 800, 0.0);
assert_eq!(fft[0], (220, 988));
}