Skip to content

Commit

Permalink
feat: implement adaptor to turn DSP instances into fundsp nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
SolarLiner committed Feb 11, 2024
1 parent 4f41dad commit eb894d0
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions src/contrib/fundsp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::dsp::DSP;
use fundsp::audionode::{AudioNode, Frame};
use fundsp::combinator::An;
use fundsp::Float;
use numeric_array::ArrayLength;
use std::marker::PhantomData;
use typenum::Unsigned;

impl<Node: AudioNode> DSP<{ Node::Inputs::USIZE }, { Node::Outputs::USIZE }> for An<Node>
Expand All @@ -19,12 +22,51 @@ where
}
}

#[derive(Debug, Clone)]
pub struct DspNode<In, Out, P>(PhantomData<In>, PhantomData<Out>, P);

pub fn dsp_node<In: Unsigned, Out: Unsigned, P: DSP<{ In::USIZE }, { Out::USIZE }>>(
dsp: P,
) -> DspNode<In, Out, P> {
DspNode(PhantomData, PhantomData, dsp)
}

impl<
In: Send + Sync + Unsigned,
Out: Send + Sync + Unsigned,
P: Send + Sync + DSP<{ In::USIZE }, { Out::USIZE }>,
> AudioNode for DspNode<In, Out, P>
where
Self: Clone,
P::Sample: Float,
In: ArrayLength<P::Sample>,
Out: ArrayLength<P::Sample>,
{
const ID: u64 = 0;
type Sample = P::Sample;
type Inputs = In;
type Outputs = Out;
type Setting = ();

fn tick(
&mut self,
input: &Frame<Self::Sample, Self::Inputs>,
) -> Frame<Self::Sample, Self::Outputs> {
let input = std::array::from_fn(|i| input[i]);
let output = self.2.process(input.into());
Frame::from_iter(output)
}
}

#[cfg(test)]
mod tests {
use crate::dsp::{utils::slice_to_mono_block_mut, DSPBlock};

use crate::dsp::blocks::Integrator;
use fundsp::hacker32::*;

use super::*;

#[test]
fn test_wrapper() {
let mut dsp = sine_hz(440.0) * sine_hz(10.0);
Expand All @@ -34,4 +76,15 @@ mod tests {

insta::assert_csv_snapshot!(&output as &[_], { "[]" => insta::rounded_redaction(3) })
}

#[test]
fn test_dsp_node() {
let mut integrator_node = dsp_node::<U1, U1, _>(Integrator::<f32>::default());
integrator_node.filter_mono(0.0);
integrator_node.filter_mono(1.0);
let actual = integrator_node.filter_mono(0.0);
let expected = 1.0;

assert_eq!(expected, actual);
}
}

0 comments on commit eb894d0

Please sign in to comment.