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 /*******************************************************************
18 * A test result running on Pixel 3 for comparison.
19 * The first parameter indicates the channel mask index.
20 * The second parameter indicates the effect index.
21 * 0: Automatic Gain Control,
22 * 1: Acoustic Echo Canceler,
23 * 2: Noise Suppressor,
24 * 3: Automatic Gain Control 2
25 * ---------------------------------------------------------------
26 * Benchmark Time CPU Iterations
27 * ---------------------------------------------------------------
28 * BM_PREPROCESSING/1/0 48179 ns 48041 ns 12349
29 * BM_PREPROCESSING/1/1 57559 ns 57403 ns 12270
30 * BM_PREPROCESSING/1/2 17524 ns 17466 ns 39982
31 * BM_PREPROCESSING/1/3 2608 ns 2599 ns 268399
32 * BM_PREPROCESSING/2/0 94198 ns 93926 ns 7470
33 * BM_PREPROCESSING/2/1 109196 ns 108899 ns 6459
34 * BM_PREPROCESSING/2/2 34098 ns 33986 ns 20576
35 * BM_PREPROCESSING/2/3 3231 ns 3221 ns 216606
36 * BM_PREPROCESSING/3/0 141532 ns 141132 ns 5030
37 * BM_PREPROCESSING/3/1 161199 ns 160745 ns 4387
38 * BM_PREPROCESSING/3/2 50663 ns 50535 ns 13619
39 * BM_PREPROCESSING/3/3 3967 ns 3955 ns 177005
40 * BM_PREPROCESSING/4/0 187032 ns 186486 ns 3706
41 * BM_PREPROCESSING/4/1 212872 ns 212264 ns 3304
42 * BM_PREPROCESSING/4/2 67649 ns 67476 ns 10128
43 * BM_PREPROCESSING/4/3 4728 ns 4713 ns 148547
44 * BM_PREPROCESSING/5/0 233874 ns 233188 ns 2954
45 * BM_PREPROCESSING/5/1 262798 ns 262052 ns 2680
46 * BM_PREPROCESSING/5/2 84592 ns 84368 ns 8203
47 * BM_PREPROCESSING/5/3 5472 ns 5455 ns 127784
48 * BM_PREPROCESSING/6/0 284777 ns 283911 ns 2468
49 * BM_PREPROCESSING/6/1 315631 ns 314726 ns 2233
50 * BM_PREPROCESSING/6/2 101200 ns 100931 ns 6802
51 * BM_PREPROCESSING/6/3 6152 ns 6133 ns 113951
52 * BM_PREPROCESSING/7/0 327207 ns 326153 ns 2112
53 * BM_PREPROCESSING/7/1 367510 ns 366410 ns 1915
54 * BM_PREPROCESSING/7/2 118574 ns 118250 ns 5795
55 * BM_PREPROCESSING/7/3 6956 ns 6935 ns 100783
56 * BM_PREPROCESSING/8/0 372603 ns 371470 ns 1880
57 * BM_PREPROCESSING/8/1 418882 ns 417625 ns 1685
58 * BM_PREPROCESSING/8/2 136155 ns 135777 ns 4986
59 * BM_PREPROCESSING/8/3 7734 ns 7711 ns 91581
60 * BM_PREPROCESSING/9/0 424795 ns 423464 ns 1657
61 * BM_PREPROCESSING/9/1 469073 ns 467687 ns 1506
62 * BM_PREPROCESSING/9/2 153170 ns 152737 ns 4519
63 * BM_PREPROCESSING/9/3 8393 ns 8363 ns 83603
64 * BM_PREPROCESSING/10/0 472440 ns 470926 ns 1489
65 * BM_PREPROCESSING/10/1 516984 ns 515480 ns 1000
66 * BM_PREPROCESSING/10/2 168802 ns 168348 ns 4097
67 * BM_PREPROCESSING/10/3 9127 ns 9100 ns 76913
68 * BM_PREPROCESSING/11/0 509690 ns 508113 ns 1360
69 * BM_PREPROCESSING/11/1 569076 ns 567390 ns 1310
70 * BM_PREPROCESSING/11/2 185678 ns 185165 ns 3729
71 * BM_PREPROCESSING/11/3 9789 ns 9760 ns 71342
72 * BM_PREPROCESSING/12/0 563858 ns 562108 ns 1270
73 * BM_PREPROCESSING/12/1 619656 ns 617791 ns 1198
74 * BM_PREPROCESSING/12/2 202882 ns 202316 ns 3406
75 * BM_PREPROCESSING/12/3 10610 ns 10579 ns 66287
76 * BM_PREPROCESSING/13/0 602944 ns 601094 ns 1167
77 * BM_PREPROCESSING/13/1 675401 ns 673293 ns 1107
78 * BM_PREPROCESSING/13/2 220677 ns 220051 ns 3131
79 * BM_PREPROCESSING/13/3 11301 ns 11265 ns 62022
80 * BM_PREPROCESSING/14/0 659495 ns 657375 ns 1071
81 * BM_PREPROCESSING/14/1 726551 ns 724295 ns 1024
82 * BM_PREPROCESSING/14/2 238595 ns 237922 ns 2901
83 * BM_PREPROCESSING/14/3 11941 ns 11906 ns 58788
84 * BM_PREPROCESSING/15/0 698377 ns 696134 ns 1014
85 * BM_PREPROCESSING/15/1 772532 ns 770217 ns 960
86 * BM_PREPROCESSING/15/2 253219 ns 252505 ns 2736
87 * BM_PREPROCESSING/15/3 12669 ns 12632 ns 55452
88 * BM_PREPROCESSING/16/0 742054 ns 739708 ns 936
89 * BM_PREPROCESSING/16/1 828029 ns 825484 ns 902
90 * BM_PREPROCESSING/16/2 272419 ns 271658 ns 2545
91 * BM_PREPROCESSING/16/3 13473 ns 13431 ns 52088
92 * BM_PREPROCESSING/17/0 794444 ns 791916 ns 891
93 * BM_PREPROCESSING/17/1 879429 ns 876704 ns 841
94 * BM_PREPROCESSING/17/2 290059 ns 289216 ns 2391
95 * BM_PREPROCESSING/17/3 14257 ns 14210 ns 49425
96 * BM_PREPROCESSING/18/0 852221 ns 849430 ns 839
97 * BM_PREPROCESSING/18/1 931121 ns 928308 ns 799
98 * BM_PREPROCESSING/18/2 307995 ns 307104 ns 2253
99 * BM_PREPROCESSING/18/3 14947 ns 14900 ns 46872
100 * BM_PREPROCESSING/19/0 888752 ns 885893 ns 781
101 * BM_PREPROCESSING/19/1 983398 ns 980285 ns 756
102 * BM_PREPROCESSING/19/2 325669 ns 324705 ns 2132
103 * BM_PREPROCESSING/19/3 15677 ns 15629 ns 44693
104 * BM_PREPROCESSING/20/0 933651 ns 930697 ns 746
105 * BM_PREPROCESSING/20/1 1033396 ns 1030235 ns 713
106 * BM_PREPROCESSING/20/2 342081 ns 341077 ns 2031
107 * BM_PREPROCESSING/20/3 16422 ns 16370 ns 42622
108 * BM_PREPROCESSING/21/0 982521 ns 979388 ns 706
109 * BM_PREPROCESSING/21/1 1085340 ns 1081926 ns 682
110 * BM_PREPROCESSING/21/2 360862 ns 359810 ns 1926
111 * BM_PREPROCESSING/21/3 17161 ns 17107 ns 40885
112 * BM_PREPROCESSING/22/0 1043560 ns 1040219 ns 678
113 * BM_PREPROCESSING/22/1 1137203 ns 1133687 ns 653
114 * BM_PREPROCESSING/22/2 377421 ns 376315 ns 1841
115 * BM_PREPROCESSING/22/3 17903 ns 17847 ns 38984
116 * BM_PREPROCESSING/23/0 1090097 ns 1086523 ns 650
117 * BM_PREPROCESSING/23/1 1199267 ns 1194231 ns 619
118 * BM_PREPROCESSING/23/2 395429 ns 394263 ns 1759
119 * BM_PREPROCESSING/23/3 18879 ns 18818 ns 37242
120 * BM_PREPROCESSING/24/0 1128638 ns 1125076 ns 629
121 * BM_PREPROCESSING/24/1 1239909 ns 1236019 ns 598
122 * BM_PREPROCESSING/24/2 414294 ns 413055 ns 1680
123 * BM_PREPROCESSING/24/3 19583 ns 19521 ns 35771
124 *******************************************************************/
125
126 #include <audio_effects/effect_aec.h>
127 #include <audio_effects/effect_agc.h>
128 #include <array>
129 #include <climits>
130 #include <cstdlib>
131 #include <random>
132 #include <vector>
133 #include <audio_effects/effect_agc2.h>
134 #include <audio_effects/effect_ns.h>
135 #include <benchmark/benchmark.h>
136 #include <hardware/audio_effect.h>
137 #include <log/log.h>
138 #include <sys/stat.h>
139 #include <system/audio.h>
140
141 extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM;
142
143 constexpr int kSampleRate = 16000;
144 constexpr float kTenMilliSecVal = 0.01;
145 constexpr unsigned int kStreamDelayMs = 0;
146 constexpr effect_uuid_t kEffectUuids[] = {
147 // agc uuid
148 {0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
149 // aec uuid
150 {0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
151 // ns uuid
152 {0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
153 // agc2 uuid
154 {0x89f38e65, 0xd4d2, 0x4d64, 0xad0e, {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}},
155 };
156 constexpr size_t kNumEffectUuids = std::size(kEffectUuids);
157 constexpr audio_channel_mask_t kChMasks[] = {
158 AUDIO_CHANNEL_INDEX_MASK_1, AUDIO_CHANNEL_INDEX_MASK_2, AUDIO_CHANNEL_INDEX_MASK_3,
159 AUDIO_CHANNEL_INDEX_MASK_4, AUDIO_CHANNEL_INDEX_MASK_5, AUDIO_CHANNEL_INDEX_MASK_6,
160 AUDIO_CHANNEL_INDEX_MASK_7, AUDIO_CHANNEL_INDEX_MASK_8, AUDIO_CHANNEL_INDEX_MASK_9,
161 AUDIO_CHANNEL_INDEX_MASK_10, AUDIO_CHANNEL_INDEX_MASK_11, AUDIO_CHANNEL_INDEX_MASK_12,
162 AUDIO_CHANNEL_INDEX_MASK_13, AUDIO_CHANNEL_INDEX_MASK_14, AUDIO_CHANNEL_INDEX_MASK_15,
163 AUDIO_CHANNEL_INDEX_MASK_16, AUDIO_CHANNEL_INDEX_MASK_17, AUDIO_CHANNEL_INDEX_MASK_18,
164 AUDIO_CHANNEL_INDEX_MASK_19, AUDIO_CHANNEL_INDEX_MASK_20, AUDIO_CHANNEL_INDEX_MASK_21,
165 AUDIO_CHANNEL_INDEX_MASK_22, AUDIO_CHANNEL_INDEX_MASK_23, AUDIO_CHANNEL_INDEX_MASK_24,
166 };
167 constexpr size_t kNumChMasks = std::size(kChMasks);
168
169 // types of pre processing modules
170 enum PreProcId {
171 PREPROC_AGC, // Automatic Gain Control
172 PREPROC_AEC, // Acoustic Echo Canceler
173 PREPROC_NS, // Noise Suppressor
174 PREPROC_AGC2, // Automatic Gain Control 2
175 PREPROC_NUM_EFFECTS
176 };
177
preProcCreateEffect(effect_handle_t * pEffectHandle,uint32_t effectType,effect_config_t * pConfig,int sessionId,int ioId)178 int preProcCreateEffect(effect_handle_t* pEffectHandle, uint32_t effectType,
179 effect_config_t* pConfig, int sessionId, int ioId) {
180 if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&kEffectUuids[effectType],
181 sessionId, ioId, pEffectHandle);
182 status != 0) {
183 ALOGE("Audio Preprocessing create returned an error = %d\n", status);
184 return EXIT_FAILURE;
185 }
186 int reply = 0;
187 uint32_t replySize = sizeof(reply);
188 if (effectType == PREPROC_AEC) {
189 if (int status = (**pEffectHandle)
190 ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG_REVERSE,
191 sizeof(effect_config_t), pConfig, &replySize, &reply);
192 status != 0) {
193 ALOGE("Set config reverse command returned an error = %d\n", status);
194 return EXIT_FAILURE;
195 }
196 }
197 if (int status = (**pEffectHandle)
198 ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG,
199 sizeof(effect_config_t), pConfig, &replySize, &reply);
200 status != 0) {
201 ALOGE("Set config command returned an error = %d\n", status);
202 return EXIT_FAILURE;
203 }
204 return reply;
205 }
206
preProcSetConfigParam(effect_handle_t effectHandle,uint32_t paramType,uint32_t paramValue)207 int preProcSetConfigParam(effect_handle_t effectHandle, uint32_t paramType, uint32_t paramValue) {
208 int reply = 0;
209 uint32_t replySize = sizeof(reply);
210 uint32_t paramData[2] = {paramType, paramValue};
211 effect_param_t* effectParam = (effect_param_t*)malloc(sizeof(*effectParam) + sizeof(paramData));
212 memcpy(&effectParam->data[0], ¶mData[0], sizeof(paramData));
213 effectParam->psize = sizeof(paramData[0]);
214 (*effectHandle)
215 ->command(effectHandle, EFFECT_CMD_SET_PARAM, sizeof(effect_param_t), effectParam,
216 &replySize, &reply);
217 free(effectParam);
218 return reply;
219 }
220
preProcGetShortVal(float paramValue)221 short preProcGetShortVal(float paramValue) {
222 return static_cast<short>(paramValue * std::numeric_limits<short>::max());
223 }
224
BM_PREPROCESSING(benchmark::State & state)225 static void BM_PREPROCESSING(benchmark::State& state) {
226 const size_t chMask = kChMasks[state.range(0) - 1];
227 const size_t channelCount = audio_channel_count_from_in_mask(chMask);
228
229 PreProcId effectType = (PreProcId)state.range(1);
230
231 int32_t sessionId = 1;
232 int32_t ioId = 1;
233 effect_handle_t effectHandle = nullptr;
234 effect_config_t config{};
235 config.inputCfg.samplingRate = config.outputCfg.samplingRate = kSampleRate;
236 config.inputCfg.channels = config.outputCfg.channels = chMask;
237 config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
238
239 if (int status = preProcCreateEffect(&effectHandle, state.range(1), &config, sessionId, ioId);
240 status != 0) {
241 ALOGE("Create effect call returned error %i", status);
242 return;
243 }
244
245 int reply = 0;
246 uint32_t replySize = sizeof(reply);
247 if (int status =
248 (*effectHandle)
249 ->command(effectHandle, EFFECT_CMD_ENABLE, 0, nullptr, &replySize, &reply);
250 status != 0) {
251 ALOGE("Command enable call returned error %d\n", reply);
252 return;
253 }
254
255 // Initialize input buffer with deterministic pseudo-random values
256 const int frameLength = (int)(kSampleRate * kTenMilliSecVal);
257 std::minstd_rand gen(chMask);
258 std::uniform_real_distribution<> dis(-1.0f, 1.0f);
259 std::vector<short> in(frameLength * channelCount);
260 for (auto& i : in) {
261 i = preProcGetShortVal(dis(gen));
262 }
263 std::vector<short> farIn(frameLength * channelCount);
264 for (auto& i : farIn) {
265 i = preProcGetShortVal(dis(gen));
266 }
267 std::vector<short> out(frameLength * channelCount);
268
269 // Run the test
270 for (auto _ : state) {
271 benchmark::DoNotOptimize(in.data());
272 benchmark::DoNotOptimize(out.data());
273 benchmark::DoNotOptimize(farIn.data());
274
275 audio_buffer_t inBuffer = {.frameCount = (size_t)frameLength, .s16 = in.data()};
276 audio_buffer_t outBuffer = {.frameCount = (size_t)frameLength, .s16 = out.data()};
277 audio_buffer_t farInBuffer = {.frameCount = (size_t)frameLength, .s16 = farIn.data()};
278
279 if (PREPROC_AEC == effectType) {
280 if (int status =
281 preProcSetConfigParam(effectHandle, AEC_PARAM_ECHO_DELAY, kStreamDelayMs);
282 status != 0) {
283 ALOGE("preProcSetConfigParam returned Error %d\n", status);
284 return;
285 }
286 }
287 if (int status = (*effectHandle)->process(effectHandle, &inBuffer, &outBuffer);
288 status != 0) {
289 ALOGE("\nError: Process i = %d returned with error %d\n", (int)state.range(1), status);
290 return;
291 }
292 if (PREPROC_AEC == effectType) {
293 if (int status =
294 (*effectHandle)->process_reverse(effectHandle, &farInBuffer, &outBuffer);
295 status != 0) {
296 ALOGE("\nError: Process reverse i = %d returned with error %d\n",
297 (int)state.range(1), status);
298 return;
299 }
300 }
301 }
302 benchmark::ClobberMemory();
303
304 state.SetComplexityN(state.range(0));
305
306 if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(effectHandle); status != 0) {
307 ALOGE("release_effect returned an error = %d\n", status);
308 return;
309 }
310 }
311
preprocessingArgs(benchmark::internal::Benchmark * b)312 static void preprocessingArgs(benchmark::internal::Benchmark* b) {
313 for (int i = 1; i <= (int)kNumChMasks; i++) {
314 for (int j = 0; j < (int)kNumEffectUuids; ++j) {
315 b->Args({i, j});
316 }
317 }
318 }
319
320 BENCHMARK(BM_PREPROCESSING)->Apply(preprocessingArgs);
321
322 BENCHMARK_MAIN();
323