// Copyright (c) 2021 Weird Constructor // 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, GraphFun, GraphAtomData, DspNode, LedPhaseVals, NodeContext }; use crate::dsp::helpers::{TrigSignal}; #[macro_export] macro_rules! fa_test_s { ($formatter: expr, $v: expr, $denorm_v: expr) => { { let s = match ($v.round() as usize) { 0 => "Zero", 1 => "One", 2 => "Two", 3 => "Three", 4 => "Four", 5 => "Five", 6 => "Six", 7 => "Seven", 8 => "Eigth", 9 => "Nine", 10 => "Ten", _ => "?", }; write!($formatter, "{}", s) } } } /// A simple amplifier #[derive(Debug, Clone)] pub struct Test { trig_sig: TrigSignal, trigger: bool, } impl Test { pub fn new(_nid: &NodeId) -> Self { Self { trigger: false, trig_sig: TrigSignal::new(), } } pub const f : &'static str = "F Test"; pub const p : &'static str = "Test p\nAn unsmoothed parameter for automated tests."; pub const trig: &'static str = "Test trig\nA trigger input, that will create a short pulse on the 'tsig' output.\nRange: (-1..1)"; pub const sig : &'static str = "Test sig\nThe output of p as signal"; pub const tsig : &'static str = "Test tsig\nA short trigger pulse will be generated when the 'trig' input is triggered."; pub const out2 : &'static str = "Test out2\nA test output that will emit 1.0 if output 'sig' is connected."; pub const out3 : &'static str = "Test out3\nA test output that will emit 1.0 if input 'f' is connected."; pub const out4 : &'static str = "Test out4\n"; pub const outc : &'static str = "Test outc\nEmits a number that defines the out_connected bitmask. Used only for testing!"; pub const DESC : &'static str = r#""#; pub const HELP : &'static str = r#""#; } impl DspNode for Test { fn outputs() -> usize { 2 } fn set_sample_rate(&mut self, srate: f32) { self.trig_sig.set_sample_rate(srate); } fn reset(&mut self) { self.trig_sig.reset(); } #[inline] fn process( &mut self, ctx: &mut T, _ectx: &mut NodeExecContext, nctx: &NodeContext, atoms: &[SAtom], _inputs: &[ProcBuf], outputs: &mut [ProcBuf], _led: LedPhaseVals) { use crate::dsp::{out_idx, at, is_out_con, out_buf, is_in_con}; let p = at::Test::p(atoms); let trig = at::Test::trig(atoms); let tsig = out_idx::Test::tsig(); let mut out2 = out_buf::Test::out2(outputs); let mut out3 = out_buf::Test::out3(outputs); let mut outc = out_buf::Test::outc(outputs); let (out, tsig) = outputs.split_at_mut(tsig); let out = &mut out[0]; let tsig = &mut tsig[0]; let mut trigger = trig.i(); if !self.trigger && trigger > 0 { self.trigger = true; } else if !self.trigger && trigger == 0 { self.trigger = false; } else if self.trigger { trigger = 0; } for frame in 0..ctx.nframes() { if trigger > 0 { self.trig_sig.trigger(); trigger = 0; } out.write(frame, p.f()); let t = self.trig_sig.next(); tsig.write(frame, t); out2.write(frame, if is_out_con::Test::sig(nctx) { 1.0 } else { 0.0 }); out3.write(frame, if is_in_con::Test::f(nctx) { 1.0 } else { 0.0 }); outc.write(frame, nctx.out_connected as f32); } } fn graph_fun() -> Option { Some(Box::new(|_gd: &dyn GraphAtomData, _init: bool, x: f32, _xn: f32| -> f32 { x })) } }