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