insta_fun/
input.rs

1use fundsp::hacker::AudioUnit;
2
3/// Input provided to the audio unit
4#[derive(Default)]
5pub enum InputSource {
6    /// No input
7    #[default]
8    None,
9    /// Input provided by a channel vec
10    ///
11    /// - First vec contains all **channels**
12    /// - Second vec contains **samples** per channel
13    VecByChannel(Vec<Vec<f32>>),
14    /// Input provided by a tick vec
15    ///
16    /// - First vec contains all **ticks**
17    /// - Second vec contains **samples** for all **channels** per tick
18    VecByTick(Vec<Vec<f32>>),
19    /// Input **repeated** on every tick
20    ///
21    /// - Vector contains **samples** for all **channels** for **one** tick
22    Flat(Vec<f32>),
23    /// Input provided by a generator function
24    ///
25    /// - First argument is the sample index
26    /// - Second argument is the channel index
27    Generator(Box<dyn Fn(usize, usize) -> f32>),
28    /// Input provided by an audio unit
29    ///
30    /// Number of outputs of the audio unit must match
31    /// the number of inputs to the test target
32    ///
33    /// * if you need to set sample rate on input unit do that upfront
34    Unit(Box<dyn AudioUnit>),
35}
36
37impl InputSource {
38    pub fn impulse() -> Self {
39        Self::Generator(Box::new(|i, _| if i == 0 { 1.0 } else { 0.0 }))
40    }
41    pub fn sine(freq: f32, sample_rate: f32) -> Self {
42        Self::Generator(Box::new(move |i, _| {
43            let phase = 2.0 * std::f32::consts::PI * freq * i as f32 / sample_rate;
44            phase.sin()
45        }))
46    }
47
48    pub fn make_data(&mut self, num_inputs: usize, num_samples: usize) -> Vec<Vec<f32>> {
49        match self {
50            InputSource::None => vec![vec![0.0; num_samples]; num_inputs],
51            InputSource::VecByChannel(data) => {
52                assert_eq!(
53                    data.len(),
54                    num_inputs,
55                    "Input vec size mismatch. Expected {} channels, got {}",
56                    num_inputs,
57                    data.len()
58                );
59                assert!(
60                    data.iter().all(|v| v.len() == num_samples),
61                    "Input vec size mismatch. Expected {} samples per channel, got {}",
62                    num_samples,
63                    data.iter().map(|v| v.len()).max().unwrap_or(0)
64                );
65                data.to_vec()
66            }
67            InputSource::VecByTick(data) => {
68                assert!(
69                    data.iter().all(|v| v.len() == num_inputs),
70                    "Input vec size mismatch. Expected {} channels, got {}",
71                    num_inputs,
72                    data.iter().map(|v| v.len()).max().unwrap_or(0)
73                );
74                assert_eq!(
75                    data.len(),
76                    num_samples,
77                    "Input vec size mismatch. Expected {} samples, got {}",
78                    num_samples,
79                    data.len()
80                );
81                (0..num_inputs)
82                    .map(|ch| (0..num_samples).map(|i| data[i][ch]).collect())
83                    .collect()
84            }
85            InputSource::Flat(data) => {
86                assert_eq!(
87                    data.len(),
88                    num_inputs,
89                    "Input vec size mismatch. Expected {} channels, got {}",
90                    num_inputs,
91                    data.len()
92                );
93                (0..num_inputs)
94                    .map(|ch| (0..num_samples).map(|_| data[ch]).collect())
95                    .collect()
96            }
97            InputSource::Generator(generator_fn) => (0..num_inputs)
98                .map(|ch| (0..num_samples).map(|i| generator_fn(i, ch)).collect())
99                .collect(),
100            InputSource::Unit(unit) => {
101                let mut data = vec![vec![0.0; num_samples]; num_inputs];
102                for i in 0..num_samples {
103                    let mut outputs = vec![0.0; num_inputs];
104                    unit.tick(&[], &mut outputs);
105                    for slc in data.iter_mut() {
106                        slc[i] = outputs[i];
107                    }
108                }
109                data
110            }
111        }
112    }
113}