1 use audio_mixer::{Channel, Mixer};
2 use criterion::{black_box, criterion_group, criterion_main, Criterion};
3 
4 use std::any::{Any, TypeId};
5 
criterion_benchmark(c: &mut Criterion)6 fn criterion_benchmark(c: &mut Criterion) {
7     let frames = 512;
8     c.bench_function("downmix_f32", |b| {
9         b.iter(|| downmix::<f32>(black_box(frames)))
10     });
11     c.bench_function("downmix_i16", |b| {
12         b.iter(|| downmix::<i16>(black_box(frames)))
13     });
14     c.bench_function("upmix_f32", |b| b.iter(|| upmix::<f32>(black_box(frames))));
15     c.bench_function("upmix_i16", |b| b.iter(|| upmix::<i16>(black_box(frames))));
16 }
17 
downmix<T>(frames: usize) where T: Clone + Default + From<u8> + ?Sized + Any,18 fn downmix<T>(frames: usize)
19 where
20     T: Clone + Default + From<u8> + ?Sized + Any,
21 {
22     // Downmix from 5.1 to stereo.
23     let input_channels = [
24         Channel::FrontLeft,
25         Channel::FrontRight,
26         Channel::FrontCenter,
27         Channel::LowFrequency,
28         Channel::BackLeft,
29         Channel::BackRight,
30     ];
31     let output_channels = [Channel::FrontLeft, Channel::FrontRight];
32     mix::<T>(&input_channels, &output_channels, frames);
33 }
34 
upmix<T>(frames: usize) where T: Clone + Default + From<u8> + ?Sized + Any,35 fn upmix<T>(frames: usize)
36 where
37     T: Clone + Default + From<u8> + ?Sized + Any,
38 {
39     // upmix from mono to stereo.
40     let input_channels = [Channel::FrontCenter];
41     let output_channels = [Channel::FrontLeft, Channel::FrontRight];
42     mix::<T>(&input_channels, &output_channels, frames);
43 }
44 
mix<T>(input_channels: &[Channel], output_channels: &[Channel], frames: usize) where T: Clone + Default + From<u8> + ?Sized + Any,45 fn mix<T>(input_channels: &[Channel], output_channels: &[Channel], frames: usize)
46 where
47     T: Clone + Default + From<u8> + ?Sized + Any,
48 {
49     if TypeId::of::<T>() == TypeId::of::<f32>() {
50         let (input_buffer, mut output_buffer) = create_buffers::<f32>(
51             input_channels.len() * frames,
52             output_channels.len() * frames,
53         );
54         let mut in_buf = input_buffer.chunks(input_channels.len());
55         let mut out_buf = output_buffer.chunks_mut(output_channels.len());
56         let mixer = Mixer::<f32>::new(input_channels, output_channels);
57         for _ in 0..frames {
58             mixer.mix(in_buf.next().unwrap(), out_buf.next().unwrap());
59         }
60     } else if TypeId::of::<T>() == TypeId::of::<i16>() {
61         let (input_buffer, mut output_buffer) = create_buffers::<i16>(
62             input_channels.len() * frames,
63             output_channels.len() * frames,
64         );
65         let mut in_buf = input_buffer.chunks(input_channels.len());
66         let mut out_buf = output_buffer.chunks_mut(output_channels.len());
67         let mixer = Mixer::<i16>::new(input_channels, output_channels);
68         for _ in 0..frames {
69             mixer.mix(in_buf.next().unwrap(), out_buf.next().unwrap());
70         }
71     } else {
72         panic!("Unsupport type");
73     }
74 }
75 
create_buffers<T: Clone + Default + From<u8>>( input_size: usize, output_size: usize, ) -> (Vec<T>, Vec<T>)76 fn create_buffers<T: Clone + Default + From<u8>>(
77     input_size: usize,
78     output_size: usize,
79 ) -> (Vec<T>, Vec<T>) {
80     let mut input_buffer = default_buffer::<T>(input_size);
81     for (i, data) in input_buffer.iter_mut().enumerate() {
82         *data = T::from((i + 1) as u8);
83     }
84     let output_buffer = default_buffer::<T>(output_size);
85     (input_buffer, output_buffer)
86 }
87 
default_buffer<T: Clone + Default>(size: usize) -> Vec<T>88 fn default_buffer<T: Clone + Default>(size: usize) -> Vec<T> {
89     let mut v = Vec::with_capacity(size);
90     v.resize(size, T::default());
91     v
92 }
93 
94 criterion_group!(benches, criterion_benchmark);
95 criterion_main!(benches);
96