• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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], &paramData[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