1use fundsp::hacker::AudioUnit;
2
3#[derive(Default)]
5pub enum InputSource {
6 #[default]
8 None,
9 VecByChannel(Vec<Vec<f32>>),
14 VecByTick(Vec<Vec<f32>>),
19 Flat(Vec<f32>),
23 Generator(Box<dyn Fn(usize, usize) -> f32>),
28 Unit(Box<dyn AudioUnit>),
35}
36
37impl From<Box<dyn AudioUnit>> for InputSource {
38 fn from(unit: Box<dyn AudioUnit>) -> Self {
39 InputSource::Unit(unit)
40 }
41}
42
43impl From<Box<dyn Fn(usize, usize) -> f32>> for InputSource {
44 fn from(generator_fn: Box<dyn Fn(usize, usize) -> f32>) -> Self {
45 InputSource::Generator(generator_fn)
46 }
47}
48
49impl From<Vec<f32>> for InputSource {
50 fn from(data: Vec<f32>) -> Self {
51 InputSource::Flat(data)
52 }
53}
54
55impl From<Vec<Vec<f32>>> for InputSource {
56 fn from(data: Vec<Vec<f32>>) -> Self {
57 InputSource::VecByChannel(data)
58 }
59}
60
61impl InputSource {
62 pub fn impulse() -> Self {
63 Self::Generator(Box::new(|i, _| if i == 0 { 1.0 } else { 0.0 }))
64 }
65 pub fn sine(freq: f32, sample_rate: f32) -> Self {
66 Self::Generator(Box::new(move |i, _| {
67 let phase = 2.0 * std::f32::consts::PI * freq * i as f32 / sample_rate;
68 phase.sin()
69 }))
70 }
71
72 pub fn make_data(&mut self, num_inputs: usize, num_samples: usize) -> Vec<Vec<f32>> {
73 match self {
74 InputSource::None => vec![vec![0.0; num_samples]; num_inputs],
75 InputSource::VecByChannel(data) => {
76 assert_eq!(
77 data.len(),
78 num_inputs,
79 "Input vec size mismatch. Expected {} channels, got {}",
80 num_inputs,
81 data.len()
82 );
83 assert!(
84 data.iter().all(|v| v.len() == num_samples),
85 "Input vec size mismatch. Expected {} samples per channel, got {}",
86 num_samples,
87 data.iter().map(|v| v.len()).max().unwrap_or(0)
88 );
89 data.to_vec()
90 }
91 InputSource::VecByTick(data) => {
92 assert!(
93 data.iter().all(|v| v.len() == num_inputs),
94 "Input vec size mismatch. Expected {} channels, got {}",
95 num_inputs,
96 data.iter().map(|v| v.len()).max().unwrap_or(0)
97 );
98 assert_eq!(
99 data.len(),
100 num_samples,
101 "Input vec size mismatch. Expected {} samples, got {}",
102 num_samples,
103 data.len()
104 );
105 (0..num_inputs)
106 .map(|ch| (0..num_samples).map(|i| data[i][ch]).collect())
107 .collect()
108 }
109 InputSource::Flat(data) => {
110 assert_eq!(
111 data.len(),
112 num_inputs,
113 "Input vec size mismatch. Expected {} channels, got {}",
114 num_inputs,
115 data.len()
116 );
117 (0..num_inputs)
118 .map(|ch| (0..num_samples).map(|_| data[ch]).collect())
119 .collect()
120 }
121 InputSource::Generator(generator_fn) => (0..num_inputs)
122 .map(|ch| (0..num_samples).map(|i| generator_fn(i, ch)).collect())
123 .collect(),
124 InputSource::Unit(unit) => {
125 let unit_outputs = unit.outputs();
129
130 let mut raw = vec![vec![0.0; num_samples]; unit_outputs];
132 (0..num_samples).for_each(|i| {
133 let mut outputs = vec![0.0; unit_outputs];
134 unit.tick(&[], &mut outputs);
135 for ch in 0..unit_outputs {
136 raw[ch][i] = outputs[ch];
137 }
138 });
139
140 let mut data = vec![vec![0.0; num_samples]; num_inputs];
144 for ch in 0..num_inputs {
145 if ch < unit_outputs {
146 data[ch] = raw[ch].clone();
147 }
148 }
149 data
150 }
151 }
152 }
153}