| /* |
| * Copyright 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <array> |
| #include <climits> |
| #include <cstdlib> |
| #include <random> |
| #include <vector> |
| #include <log/log.h> |
| #include <benchmark/benchmark.h> |
| #include <hardware/audio_effect.h> |
| #include <system/audio.h> |
| |
| extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM; |
| constexpr effect_uuid_t kEffectUuids[] = { |
| // NXP SW BassBoost |
| {0x8631f300, 0x72e2, 0x11df, 0xb57e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, |
| // NXP SW Virtualizer |
| {0x1d4033c0, 0x8557, 0x11df, 0x9f2d, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, |
| // NXP SW Equalizer |
| {0xce772f20, 0x847d, 0x11df, 0xbb17, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, |
| // NXP SW Volume |
| {0x119341a0, 0x8469, 0x11df, 0x81f9, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, |
| }; |
| |
| constexpr size_t kNumEffectUuids = std::size(kEffectUuids); |
| |
| constexpr size_t kFrameCount = 2048; |
| |
| constexpr audio_channel_mask_t kChMasks[] = { |
| AUDIO_CHANNEL_INDEX_MASK_1, AUDIO_CHANNEL_INDEX_MASK_2, AUDIO_CHANNEL_INDEX_MASK_3, |
| AUDIO_CHANNEL_INDEX_MASK_4, AUDIO_CHANNEL_INDEX_MASK_5, AUDIO_CHANNEL_INDEX_MASK_6, |
| AUDIO_CHANNEL_INDEX_MASK_7, AUDIO_CHANNEL_INDEX_MASK_8, AUDIO_CHANNEL_INDEX_MASK_9, |
| AUDIO_CHANNEL_INDEX_MASK_10, AUDIO_CHANNEL_INDEX_MASK_11, AUDIO_CHANNEL_INDEX_MASK_12, |
| AUDIO_CHANNEL_INDEX_MASK_13, AUDIO_CHANNEL_INDEX_MASK_14, AUDIO_CHANNEL_INDEX_MASK_15, |
| AUDIO_CHANNEL_INDEX_MASK_16, AUDIO_CHANNEL_INDEX_MASK_17, AUDIO_CHANNEL_INDEX_MASK_18, |
| AUDIO_CHANNEL_INDEX_MASK_19, AUDIO_CHANNEL_INDEX_MASK_20, AUDIO_CHANNEL_INDEX_MASK_21, |
| AUDIO_CHANNEL_INDEX_MASK_22, AUDIO_CHANNEL_INDEX_MASK_23, AUDIO_CHANNEL_INDEX_MASK_24, |
| }; |
| |
| constexpr size_t kNumChMasks = std::size(kChMasks); |
| constexpr int kSampleRate = 44100; |
| |
| /******************************************************************* |
| * A test result running on Pixel 3 for comparison. |
| * The first parameter indicates the number of channels. |
| * The second parameter indicates the effect. |
| * 0: Bass Boost, 1: Virtualizer, 2: Equalizer, 3: Volume |
| * ----------------------------------------------------- |
| * Benchmark Time CPU Iterations |
| * ----------------------------------------------------- |
| * BM_LVM/1/0 52123 ns 51971 ns 13437 |
| * BM_LVM/1/1 75397 ns 75175 ns 9382 |
| * BM_LVM/1/2 40253 ns 40140 ns 17418 |
| * BM_LVM/1/3 19918 ns 19860 ns 35230 |
| * BM_LVM/2/0 62455 ns 62283 ns 11214 |
| * BM_LVM/2/1 110086 ns 109751 ns 6350 |
| * BM_LVM/2/2 44017 ns 43890 ns 15982 |
| * BM_LVM/2/3 21660 ns 21596 ns 32568 |
| * BM_LVM/3/0 71925 ns 71698 ns 9745 |
| * BM_LVM/3/1 117043 ns 116754 ns 6007 |
| * BM_LVM/3/2 48899 ns 48781 ns 14334 |
| * BM_LVM/3/3 23607 ns 23540 ns 29739 |
| * BM_LVM/4/0 81296 ns 81095 ns 8632 |
| * BM_LVM/4/1 122435 ns 122132 ns 5733 |
| * BM_LVM/4/2 53744 ns 53612 ns 13068 |
| * BM_LVM/4/3 25846 ns 25783 ns 27188 |
| * BM_LVM/5/0 98557 ns 98311 ns 7120 |
| * BM_LVM/5/1 131626 ns 131269 ns 5296 |
| * BM_LVM/5/2 66892 ns 66732 ns 10458 |
| * BM_LVM/5/3 31797 ns 31721 ns 22092 |
| * BM_LVM/6/0 111880 ns 111596 ns 6278 |
| * BM_LVM/6/1 140207 ns 139846 ns 5000 |
| * BM_LVM/6/2 75683 ns 75496 ns 9253 |
| * BM_LVM/6/3 37669 ns 37571 ns 18663 |
| * BM_LVM/7/0 128265 ns 127957 ns 5470 |
| * BM_LVM/7/1 149522 ns 149159 ns 4699 |
| * BM_LVM/7/2 92024 ns 91798 ns 7631 |
| * BM_LVM/7/3 43372 ns 43268 ns 16181 |
| * BM_LVM/8/0 141897 ns 141548 ns 4945 |
| * BM_LVM/8/1 158062 ns 157661 ns 4438 |
| * BM_LVM/8/2 98042 ns 97801 ns 7151 |
| * BM_LVM/8/3 49044 ns 48923 ns 14314 |
| * BM_LVM/9/0 174692 ns 174228 ns 4026 |
| * BM_LVM/9/1 183048 ns 182560 ns 3834 |
| * BM_LVM/9/2 131020 ns 130675 ns 5347 |
| * BM_LVM/9/3 71102 ns 70915 ns 9801 |
| * BM_LVM/10/0 189079 ns 188576 ns 3699 |
| * BM_LVM/10/1 187989 ns 187472 ns 3737 |
| * BM_LVM/10/2 140093 ns 139717 ns 5007 |
| * BM_LVM/10/3 78175 ns 77963 ns 8919 |
| * BM_LVM/11/0 207577 ns 207007 ns 3371 |
| * BM_LVM/11/1 198186 ns 197640 ns 3535 |
| * BM_LVM/11/2 157214 ns 156786 ns 4459 |
| * BM_LVM/11/3 85912 ns 85681 ns 8153 |
| * BM_LVM/12/0 220861 ns 220265 ns 3169 |
| * BM_LVM/12/1 208759 ns 208184 ns 3355 |
| * BM_LVM/12/2 165533 ns 165088 ns 4234 |
| * BM_LVM/12/3 92616 ns 92364 ns 7528 |
| * BM_LVM/13/0 238573 ns 237920 ns 2945 |
| * BM_LVM/13/1 219130 ns 218520 ns 3209 |
| * BM_LVM/13/2 183193 ns 182692 ns 3830 |
| * BM_LVM/13/3 100546 ns 100274 ns 7005 |
| * BM_LVM/14/0 254820 ns 254135 ns 2748 |
| * BM_LVM/14/1 230161 ns 229530 ns 3049 |
| * BM_LVM/14/2 192195 ns 191671 ns 3635 |
| * BM_LVM/14/3 107770 ns 107477 ns 6502 |
| * BM_LVM/15/0 273695 ns 272954 ns 2531 |
| * BM_LVM/15/1 240718 ns 240049 ns 2801 |
| * BM_LVM/15/2 220914 ns 220309 ns 3191 |
| * BM_LVM/15/3 124321 ns 123978 ns 5664 |
| * BM_LVM/16/0 285769 ns 284969 ns 2459 |
| * BM_LVM/16/1 251692 ns 250983 ns 2789 |
| * BM_LVM/16/2 224554 ns 223917 ns 3132 |
| * BM_LVM/16/3 122048 ns 121706 ns 5753 |
| * BM_LVM/17/0 310027 ns 309154 ns 2266 |
| * BM_LVM/17/1 262008 ns 261259 ns 2681 |
| * BM_LVM/17/2 247530 ns 246827 ns 2842 |
| * BM_LVM/17/3 129513 ns 129146 ns 5418 |
| * BM_LVM/18/0 322755 ns 321844 ns 2173 |
| * BM_LVM/18/1 263266 ns 262514 ns 2671 |
| * BM_LVM/18/2 257606 ns 256875 ns 2731 |
| * BM_LVM/18/3 136550 ns 136164 ns 5129 |
| * BM_LVM/19/0 338551 ns 337591 ns 2069 |
| * BM_LVM/19/1 275929 ns 275134 ns 2535 |
| * BM_LVM/19/2 270331 ns 269554 ns 2596 |
| * BM_LVM/19/3 144551 ns 144138 ns 4838 |
| * BM_LVM/20/0 352633 ns 351617 ns 1993 |
| * BM_LVM/20/1 286607 ns 285713 ns 2371 |
| * BM_LVM/20/2 283541 ns 282689 ns 2407 |
| * BM_LVM/20/3 152355 ns 151904 ns 4604 |
| * BM_LVM/21/0 370557 ns 369456 ns 1889 |
| * BM_LVM/21/1 298251 ns 297351 ns 2352 |
| * BM_LVM/21/2 296806 ns 295917 ns 2364 |
| * BM_LVM/21/3 160212 ns 159735 ns 4330 |
| * BM_LVM/22/0 386431 ns 385224 ns 1826 |
| * BM_LVM/22/1 308901 ns 307925 ns 2273 |
| * BM_LVM/22/2 309077 ns 308140 ns 2274 |
| * BM_LVM/22/3 167492 ns 166987 ns 4194 |
| * BM_LVM/23/0 404455 ns 403218 ns 1729 |
| * BM_LVM/23/1 322026 ns 321014 ns 2187 |
| * BM_LVM/23/2 326616 ns 325623 ns 2152 |
| * BM_LVM/23/3 175873 ns 175328 ns 4007 |
| * BM_LVM/24/0 416949 ns 415676 ns 1684 |
| * BM_LVM/24/1 329803 ns 328779 ns 2128 |
| * BM_LVM/24/2 337648 ns 336626 ns 2080 |
| * BM_LVM/24/3 183192 ns 182634 ns 3824 |
| *******************************************************************/ |
| |
| static void BM_LVM(benchmark::State& state) { |
| const size_t chMask = kChMasks[state.range(0) - 1]; |
| const effect_uuid_t uuid = kEffectUuids[state.range(1)]; |
| const size_t channelCount = audio_channel_count_from_out_mask(chMask); |
| |
| // Initialize input buffer with deterministic pseudo-random values |
| std::minstd_rand gen(chMask); |
| std::uniform_real_distribution<> dis(-1.0f, 1.0f); |
| std::vector<float> input(kFrameCount * channelCount); |
| for (auto& in : input) { |
| in = dis(gen); |
| } |
| |
| effect_handle_t effectHandle = nullptr; |
| if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&uuid, 1, 1, &effectHandle); |
| status != 0) { |
| ALOGE("create_effect returned an error = %d\n", status); |
| return; |
| } |
| |
| effect_config_t config{}; |
| config.inputCfg.samplingRate = config.outputCfg.samplingRate = kSampleRate; |
| config.inputCfg.channels = config.outputCfg.channels = chMask; |
| config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT; |
| |
| int reply = 0; |
| uint32_t replySize = sizeof(reply); |
| if (int status = (*effectHandle) |
| ->command(effectHandle, EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t), |
| &config, &replySize, &reply); |
| status != 0) { |
| ALOGE("command returned an error = %d\n", status); |
| return; |
| } |
| |
| if (int status = |
| (*effectHandle) |
| ->command(effectHandle, EFFECT_CMD_ENABLE, 0, nullptr, &replySize, &reply); |
| status != 0) { |
| ALOGE("Command enable call returned error %d\n", reply); |
| return; |
| } |
| |
| // Run the test |
| for (auto _ : state) { |
| std::vector<float> output(kFrameCount * channelCount); |
| |
| benchmark::DoNotOptimize(input.data()); |
| benchmark::DoNotOptimize(output.data()); |
| |
| audio_buffer_t inBuffer = {.frameCount = kFrameCount, .f32 = input.data()}; |
| audio_buffer_t outBuffer = {.frameCount = kFrameCount, .f32 = output.data()}; |
| (*effectHandle)->process(effectHandle, &inBuffer, &outBuffer); |
| |
| benchmark::ClobberMemory(); |
| } |
| |
| state.SetComplexityN(state.range(0)); |
| |
| if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(effectHandle); status != 0) { |
| ALOGE("release_effect returned an error = %d\n", status); |
| return; |
| } |
| } |
| |
| static void LVMArgs(benchmark::internal::Benchmark* b) { |
| for (int i = FCC_1; i <= kNumChMasks; i++) { |
| for (int j = 0; j < kNumEffectUuids; ++j) { |
| b->Args({i, j}); |
| } |
| } |
| } |
| |
| BENCHMARK(BM_LVM)->Apply(LVMArgs); |
| |
| BENCHMARK_MAIN(); |