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