1 /*
2 * Copyright 2020 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 <array>
18 #include <climits>
19 #include <cstdlib>
20 #include <random>
21 #include <vector>
22 #include <log/log.h>
23 #include <benchmark/benchmark.h>
24 #include <hardware/audio_effect.h>
25 #include <system/audio.h>
26
27 extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM;
28 constexpr effect_uuid_t kEffectUuids[] = {
29 // NXP SW BassBoost
30 {0x8631f300, 0x72e2, 0x11df, 0xb57e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
31 // NXP SW Virtualizer
32 {0x1d4033c0, 0x8557, 0x11df, 0x9f2d, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
33 // NXP SW Equalizer
34 {0xce772f20, 0x847d, 0x11df, 0xbb17, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
35 // NXP SW Volume
36 {0x119341a0, 0x8469, 0x11df, 0x81f9, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
37 };
38
39 constexpr size_t kNumEffectUuids = std::size(kEffectUuids);
40
41 constexpr size_t kFrameCount = 2048;
42
43 constexpr audio_channel_mask_t kChMasks[] = {
44 AUDIO_CHANNEL_INDEX_MASK_1, AUDIO_CHANNEL_INDEX_MASK_2, AUDIO_CHANNEL_INDEX_MASK_3,
45 AUDIO_CHANNEL_INDEX_MASK_4, AUDIO_CHANNEL_INDEX_MASK_5, AUDIO_CHANNEL_INDEX_MASK_6,
46 AUDIO_CHANNEL_INDEX_MASK_7, AUDIO_CHANNEL_INDEX_MASK_8, AUDIO_CHANNEL_INDEX_MASK_9,
47 AUDIO_CHANNEL_INDEX_MASK_10, AUDIO_CHANNEL_INDEX_MASK_11, AUDIO_CHANNEL_INDEX_MASK_12,
48 AUDIO_CHANNEL_INDEX_MASK_13, AUDIO_CHANNEL_INDEX_MASK_14, AUDIO_CHANNEL_INDEX_MASK_15,
49 AUDIO_CHANNEL_INDEX_MASK_16, AUDIO_CHANNEL_INDEX_MASK_17, AUDIO_CHANNEL_INDEX_MASK_18,
50 AUDIO_CHANNEL_INDEX_MASK_19, AUDIO_CHANNEL_INDEX_MASK_20, AUDIO_CHANNEL_INDEX_MASK_21,
51 AUDIO_CHANNEL_INDEX_MASK_22, AUDIO_CHANNEL_INDEX_MASK_23, AUDIO_CHANNEL_INDEX_MASK_24,
52 };
53
54 constexpr size_t kNumChMasks = std::size(kChMasks);
55 constexpr int kSampleRate = 44100;
56
57 /*******************************************************************
58 * A test result running on Pixel 3 for comparison.
59 * The first parameter indicates the number of channels.
60 * The second parameter indicates the effect.
61 * 0: Bass Boost, 1: Virtualizer, 2: Equalizer, 3: Volume
62 * -----------------------------------------------------
63 * Benchmark Time CPU Iterations
64 * -----------------------------------------------------
65 * BM_LVM/1/0 52123 ns 51971 ns 13437
66 * BM_LVM/1/1 75397 ns 75175 ns 9382
67 * BM_LVM/1/2 40253 ns 40140 ns 17418
68 * BM_LVM/1/3 19918 ns 19860 ns 35230
69 * BM_LVM/2/0 62455 ns 62283 ns 11214
70 * BM_LVM/2/1 110086 ns 109751 ns 6350
71 * BM_LVM/2/2 44017 ns 43890 ns 15982
72 * BM_LVM/2/3 21660 ns 21596 ns 32568
73 * BM_LVM/3/0 71925 ns 71698 ns 9745
74 * BM_LVM/3/1 117043 ns 116754 ns 6007
75 * BM_LVM/3/2 48899 ns 48781 ns 14334
76 * BM_LVM/3/3 23607 ns 23540 ns 29739
77 * BM_LVM/4/0 81296 ns 81095 ns 8632
78 * BM_LVM/4/1 122435 ns 122132 ns 5733
79 * BM_LVM/4/2 53744 ns 53612 ns 13068
80 * BM_LVM/4/3 25846 ns 25783 ns 27188
81 * BM_LVM/5/0 98557 ns 98311 ns 7120
82 * BM_LVM/5/1 131626 ns 131269 ns 5296
83 * BM_LVM/5/2 66892 ns 66732 ns 10458
84 * BM_LVM/5/3 31797 ns 31721 ns 22092
85 * BM_LVM/6/0 111880 ns 111596 ns 6278
86 * BM_LVM/6/1 140207 ns 139846 ns 5000
87 * BM_LVM/6/2 75683 ns 75496 ns 9253
88 * BM_LVM/6/3 37669 ns 37571 ns 18663
89 * BM_LVM/7/0 128265 ns 127957 ns 5470
90 * BM_LVM/7/1 149522 ns 149159 ns 4699
91 * BM_LVM/7/2 92024 ns 91798 ns 7631
92 * BM_LVM/7/3 43372 ns 43268 ns 16181
93 * BM_LVM/8/0 141897 ns 141548 ns 4945
94 * BM_LVM/8/1 158062 ns 157661 ns 4438
95 * BM_LVM/8/2 98042 ns 97801 ns 7151
96 * BM_LVM/8/3 49044 ns 48923 ns 14314
97 * BM_LVM/9/0 174692 ns 174228 ns 4026
98 * BM_LVM/9/1 183048 ns 182560 ns 3834
99 * BM_LVM/9/2 131020 ns 130675 ns 5347
100 * BM_LVM/9/3 71102 ns 70915 ns 9801
101 * BM_LVM/10/0 189079 ns 188576 ns 3699
102 * BM_LVM/10/1 187989 ns 187472 ns 3737
103 * BM_LVM/10/2 140093 ns 139717 ns 5007
104 * BM_LVM/10/3 78175 ns 77963 ns 8919
105 * BM_LVM/11/0 207577 ns 207007 ns 3371
106 * BM_LVM/11/1 198186 ns 197640 ns 3535
107 * BM_LVM/11/2 157214 ns 156786 ns 4459
108 * BM_LVM/11/3 85912 ns 85681 ns 8153
109 * BM_LVM/12/0 220861 ns 220265 ns 3169
110 * BM_LVM/12/1 208759 ns 208184 ns 3355
111 * BM_LVM/12/2 165533 ns 165088 ns 4234
112 * BM_LVM/12/3 92616 ns 92364 ns 7528
113 * BM_LVM/13/0 238573 ns 237920 ns 2945
114 * BM_LVM/13/1 219130 ns 218520 ns 3209
115 * BM_LVM/13/2 183193 ns 182692 ns 3830
116 * BM_LVM/13/3 100546 ns 100274 ns 7005
117 * BM_LVM/14/0 254820 ns 254135 ns 2748
118 * BM_LVM/14/1 230161 ns 229530 ns 3049
119 * BM_LVM/14/2 192195 ns 191671 ns 3635
120 * BM_LVM/14/3 107770 ns 107477 ns 6502
121 * BM_LVM/15/0 273695 ns 272954 ns 2531
122 * BM_LVM/15/1 240718 ns 240049 ns 2801
123 * BM_LVM/15/2 220914 ns 220309 ns 3191
124 * BM_LVM/15/3 124321 ns 123978 ns 5664
125 * BM_LVM/16/0 285769 ns 284969 ns 2459
126 * BM_LVM/16/1 251692 ns 250983 ns 2789
127 * BM_LVM/16/2 224554 ns 223917 ns 3132
128 * BM_LVM/16/3 122048 ns 121706 ns 5753
129 * BM_LVM/17/0 310027 ns 309154 ns 2266
130 * BM_LVM/17/1 262008 ns 261259 ns 2681
131 * BM_LVM/17/2 247530 ns 246827 ns 2842
132 * BM_LVM/17/3 129513 ns 129146 ns 5418
133 * BM_LVM/18/0 322755 ns 321844 ns 2173
134 * BM_LVM/18/1 263266 ns 262514 ns 2671
135 * BM_LVM/18/2 257606 ns 256875 ns 2731
136 * BM_LVM/18/3 136550 ns 136164 ns 5129
137 * BM_LVM/19/0 338551 ns 337591 ns 2069
138 * BM_LVM/19/1 275929 ns 275134 ns 2535
139 * BM_LVM/19/2 270331 ns 269554 ns 2596
140 * BM_LVM/19/3 144551 ns 144138 ns 4838
141 * BM_LVM/20/0 352633 ns 351617 ns 1993
142 * BM_LVM/20/1 286607 ns 285713 ns 2371
143 * BM_LVM/20/2 283541 ns 282689 ns 2407
144 * BM_LVM/20/3 152355 ns 151904 ns 4604
145 * BM_LVM/21/0 370557 ns 369456 ns 1889
146 * BM_LVM/21/1 298251 ns 297351 ns 2352
147 * BM_LVM/21/2 296806 ns 295917 ns 2364
148 * BM_LVM/21/3 160212 ns 159735 ns 4330
149 * BM_LVM/22/0 386431 ns 385224 ns 1826
150 * BM_LVM/22/1 308901 ns 307925 ns 2273
151 * BM_LVM/22/2 309077 ns 308140 ns 2274
152 * BM_LVM/22/3 167492 ns 166987 ns 4194
153 * BM_LVM/23/0 404455 ns 403218 ns 1729
154 * BM_LVM/23/1 322026 ns 321014 ns 2187
155 * BM_LVM/23/2 326616 ns 325623 ns 2152
156 * BM_LVM/23/3 175873 ns 175328 ns 4007
157 * BM_LVM/24/0 416949 ns 415676 ns 1684
158 * BM_LVM/24/1 329803 ns 328779 ns 2128
159 * BM_LVM/24/2 337648 ns 336626 ns 2080
160 * BM_LVM/24/3 183192 ns 182634 ns 3824
161 *******************************************************************/
162
BM_LVM(benchmark::State & state)163 static void BM_LVM(benchmark::State& state) {
164 const size_t chMask = kChMasks[state.range(0) - 1];
165 const effect_uuid_t uuid = kEffectUuids[state.range(1)];
166 const size_t channelCount = audio_channel_count_from_out_mask(chMask);
167
168 // Initialize input buffer with deterministic pseudo-random values
169 std::minstd_rand gen(chMask);
170 std::uniform_real_distribution<> dis(-1.0f, 1.0f);
171 std::vector<float> input(kFrameCount * channelCount);
172 for (auto& in : input) {
173 in = dis(gen);
174 }
175
176 effect_handle_t effectHandle = nullptr;
177 if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&uuid, 1, 1, &effectHandle);
178 status != 0) {
179 ALOGE("create_effect returned an error = %d\n", status);
180 return;
181 }
182
183 effect_config_t config{};
184 config.inputCfg.samplingRate = config.outputCfg.samplingRate = kSampleRate;
185 config.inputCfg.channels = config.outputCfg.channels = chMask;
186 config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
187
188 int reply = 0;
189 uint32_t replySize = sizeof(reply);
190 if (int status = (*effectHandle)
191 ->command(effectHandle, EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t),
192 &config, &replySize, &reply);
193 status != 0) {
194 ALOGE("command returned an error = %d\n", status);
195 return;
196 }
197
198 if (int status =
199 (*effectHandle)
200 ->command(effectHandle, EFFECT_CMD_ENABLE, 0, nullptr, &replySize, &reply);
201 status != 0) {
202 ALOGE("Command enable call returned error %d\n", reply);
203 return;
204 }
205
206 // Run the test
207 for (auto _ : state) {
208 std::vector<float> output(kFrameCount * channelCount);
209
210 benchmark::DoNotOptimize(input.data());
211 benchmark::DoNotOptimize(output.data());
212
213 audio_buffer_t inBuffer = {.frameCount = kFrameCount, .f32 = input.data()};
214 audio_buffer_t outBuffer = {.frameCount = kFrameCount, .f32 = output.data()};
215 (*effectHandle)->process(effectHandle, &inBuffer, &outBuffer);
216
217 benchmark::ClobberMemory();
218 }
219
220 state.SetComplexityN(state.range(0));
221
222 if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(effectHandle); status != 0) {
223 ALOGE("release_effect returned an error = %d\n", status);
224 return;
225 }
226 }
227
LVMArgs(benchmark::internal::Benchmark * b)228 static void LVMArgs(benchmark::internal::Benchmark* b) {
229 for (int i = FCC_1; i <= kNumChMasks; i++) {
230 for (int j = 0; j < kNumEffectUuids; ++j) {
231 b->Args({i, j});
232 }
233 }
234 }
235
236 BENCHMARK(BM_LVM)->Apply(LVMArgs);
237
238 BENCHMARK_MAIN();
239