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