sim_lib_audio_dsp/
fixture.rs1use sim_lib_audio_graph_core::{
2 BlockArena, NullEventSink, PrepareConfig, ProcessBlock, Processor, Transport,
3};
4
5#[derive(Clone, Debug, PartialEq)]
8pub struct GoldenFixture {
9 pub name: &'static str,
11 pub sample_rate_hz: u32,
13 pub input: Vec<Vec<f32>>,
15 pub expected: Vec<Vec<f32>>,
17}
18
19impl GoldenFixture {
20 pub fn frames(&self) -> u32 {
22 self.input.first().map_or(0, Vec::len) as u32
23 }
24}
25
26pub fn r30_gain_golden_fixture() -> GoldenFixture {
28 GoldenFixture {
29 name: "r30-gain",
30 sample_rate_hz: 48_000,
31 input: vec![vec![1.0, -0.5, 0.25, 0.0, -0.25, 0.5, -1.0, 0.75]],
32 expected: vec![vec![
33 0.25, -0.125, 0.0625, 0.0, -0.0625, 0.125, -0.25, 0.1875,
34 ]],
35 }
36}
37
38pub fn r30_delay_golden_fixture() -> GoldenFixture {
40 GoldenFixture {
41 name: "r30-delay",
42 sample_rate_hz: 1_000,
43 input: vec![vec![1.0, 0.0, 0.0, 0.0, 0.0, 0.0]],
44 expected: vec![vec![0.0, 0.0, 1.0, 0.0, 0.0, 0.0]],
45 }
46}
47
48pub fn run_offline<P: Processor>(
51 processor: &mut P,
52 fixture: &GoldenFixture,
53 out_channels: usize,
54) -> Vec<Vec<f32>> {
55 let frames = fixture.frames() as usize;
56 processor.prepare(PrepareConfig::new(
57 fixture.sample_rate_hz,
58 fixture.frames(),
59 fixture.input.len() as u16,
60 out_channels as u16,
61 ));
62 let mut output = vec![vec![0.0; frames]; out_channels];
63 let input_refs: Vec<&[f32]> = fixture.input.iter().map(Vec::as_slice).collect();
64 let mut output_refs: Vec<&mut [f32]> = output.iter_mut().map(Vec::as_mut_slice).collect();
65 let mut sink = NullEventSink;
66 let mut scratch = BlockArena::with_f32_capacity(frames * out_channels.max(1));
67 let mut block = ProcessBlock {
68 frames: fixture.frames(),
69 in_audio: &input_refs,
70 out_audio: &mut output_refs,
71 in_events: &[],
72 out_events: &mut sink,
73 transport: Transport::default(),
74 scratch: &mut scratch,
75 };
76 processor.process(&mut block);
77 output
78}