1 /*
2  * Copyright 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <audio_utils/ChannelMix.h>
18 
19 #include <random>
20 #include <vector>
21 
22 #include <benchmark/benchmark.h>
23 #include <log/log.h>
24 
25 static constexpr audio_channel_mask_t kChannelPositionMasks[] = {
26     AUDIO_CHANNEL_OUT_FRONT_LEFT,
27     AUDIO_CHANNEL_OUT_FRONT_CENTER,
28     AUDIO_CHANNEL_OUT_STEREO,
29     AUDIO_CHANNEL_OUT_2POINT1,
30     AUDIO_CHANNEL_OUT_2POINT0POINT2,
31     AUDIO_CHANNEL_OUT_QUAD, // AUDIO_CHANNEL_OUT_QUAD_BACK
32     AUDIO_CHANNEL_OUT_QUAD_SIDE,
33     AUDIO_CHANNEL_OUT_SURROUND,
34     AUDIO_CHANNEL_OUT_2POINT1POINT2,
35     AUDIO_CHANNEL_OUT_3POINT0POINT2,
36     AUDIO_CHANNEL_OUT_PENTA,
37     AUDIO_CHANNEL_OUT_3POINT1POINT2,
38     AUDIO_CHANNEL_OUT_5POINT1, // AUDIO_CHANNEL_OUT_5POINT1_BACK
39     AUDIO_CHANNEL_OUT_5POINT1_SIDE,
40     AUDIO_CHANNEL_OUT_6POINT1,
41     AUDIO_CHANNEL_OUT_5POINT1POINT2,
42     AUDIO_CHANNEL_OUT_7POINT1,
43     AUDIO_CHANNEL_OUT_5POINT1POINT4,
44     AUDIO_CHANNEL_OUT_7POINT1POINT2,
45     AUDIO_CHANNEL_OUT_7POINT1POINT4,
46     AUDIO_CHANNEL_OUT_13POINT_360RA,
47     AUDIO_CHANNEL_OUT_22POINT2,
48 };
49 
50 /*
51 $ adb shell /data/benchmarktest64/channelmix_benchmark/channelmix_benchmark
52 Pixel 4XL Coral arm64 benchmark
53 
54 -----------------------------------------------------------
55 Benchmark                 Time             CPU   Iterations
56 -----------------------------------------------------------
57 BM_ChannelMix/0        2180 ns         2175 ns       321797 AUDIO_CHANNEL_OUT_MONO
58 BM_ChannelMix/1        2180 ns         2175 ns       321901
59 BM_ChannelMix/2        3265 ns         3256 ns       214957 AUDIO_CHANNEL_OUT_STEREO
60 BM_ChannelMix/3        3987 ns         3978 ns       175964 AUDIO_CHANNEL_OUT_2POINT1
61 BM_ChannelMix/4        4713 ns         4700 ns       148922 AUDIO_CHANNEL_OUT_2POINT0POINT2
62 BM_ChannelMix/5        1050 ns         1047 ns       668462 AUDIO_CHANNEL_OUT_QUAD
63 BM_ChannelMix/6        1052 ns         1049 ns       667155 AUDIO_CHANNEL_OUT_QUAD_SIDE
64 BM_ChannelMix/7        4714 ns         4701 ns       148926 AUDIO_CHANNEL_OUT_SURROUND
65 BM_ChannelMix/8        5437 ns         5422 ns       129099 AUDIO_CHANNEL_OUT_2POINT1POINT2
66 BM_ChannelMix/9        5437 ns         5422 ns       129108 AUDIO_CHANNEL_OUT_3POINT0POINT2
67 BM_ChannelMix/10       5435 ns         5422 ns       129083 AUDIO_CHANNEL_OUT_PENTA
68 BM_ChannelMix/11       6161 ns         6143 ns       113945 AUDIO_CHANNEL_OUT_3POINT1POINT2
69 BM_ChannelMix/12       2511 ns         2504 ns       279645 AUDIO_CHANNEL_OUT_5POINT1
70 BM_ChannelMix/13       2511 ns         2503 ns       279621 AUDIO_CHANNEL_OUT_5POINT1_SIDE
71 BM_ChannelMix/14       6882 ns         6865 ns       101946 AUDIO_CHANNEL_OUT_6POINT1
72 BM_ChannelMix/15       7607 ns         7586 ns        92271 AUDIO_CHANNEL_OUT_5POINT1POINT2
73 BM_ChannelMix/16       2812 ns         2804 ns       249729 AUDIO_CHANNEL_OUT_7POINT1
74 BM_ChannelMix/17       9055 ns         9032 ns        77517 AUDIO_CHANNEL_OUT_5POINT1POINT4
75 BM_ChannelMix/18       9055 ns         9031 ns        77477 AUDIO_CHANNEL_OUT_7POINT1POINT2
76 BM_ChannelMix/19      10510 ns        10479 ns        66762 AUDIO_CHANNEL_OUT_7POINT1POINT4
77 BM_ChannelMix/20      11293 ns        11262 ns        62135 AUDIO_CHANNEL_OUT_13POINT_360RA
78 BM_ChannelMix/21      19886 ns        19829 ns        35265 AUDIO_CHANNEL_OUT_22POINT2
79 */
80 
BM_ChannelMix(benchmark::State & state)81 static void BM_ChannelMix(benchmark::State& state) {
82     const audio_channel_mask_t channelMask = kChannelPositionMasks[state.range(0)];
83     using namespace ::android::audio_utils::channels;
84     ChannelMix channelMix(channelMask);
85     constexpr size_t frameCount = 1024;
86     size_t inChannels = audio_channel_count_from_out_mask(channelMask);
87     std::vector<float> input(inChannels * frameCount);
88     std::vector<float> output(FCC_2 * frameCount);
89     constexpr float amplitude = 0.01f;
90 
91     std::minstd_rand gen(channelMask);
92     std::uniform_real_distribution<> dis(-amplitude, amplitude);
93     for (auto& in : input) {
94         in = dis(gen);
95     }
96 
97     assert(channelMix.getInputChannelMask() != AUDIO_CHANNEL_NONE);
98     // Run the test
99     for (auto _ : state) {
100         benchmark::DoNotOptimize(input.data());
101         benchmark::DoNotOptimize(output.data());
102         channelMix.process(input.data(), output.data(), frameCount, false /* accumulate */);
103         benchmark::ClobberMemory();
104     }
105 
106     state.SetComplexityN(inChannels);
107     state.SetLabel(audio_channel_out_mask_to_string(channelMask));
108 }
109 
ChannelMixArgs(benchmark::internal::Benchmark * b)110 static void ChannelMixArgs(benchmark::internal::Benchmark* b) {
111     for (int i = 0; i < (int)std::size(kChannelPositionMasks); i++) {
112         b->Args({i});
113     }
114 }
115 
116 BENCHMARK(BM_ChannelMix)->Apply(ChannelMixArgs);
117 
118 BENCHMARK_MAIN();
119