/* * 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. */ /******************************************************************* * A test result running on Pixel 3 for comparison. * The first parameter indicates the channel mask index. * The second parameter indicates the effect index. * 0: Automatic Gain Control, * 1: Acoustic Echo Canceler, * 2: Noise Suppressor, * 3: Automatic Gain Control 2 * --------------------------------------------------------------- * Benchmark Time CPU Iterations * --------------------------------------------------------------- * BM_PREPROCESSING/1/0 48179 ns 48041 ns 12349 * BM_PREPROCESSING/1/1 57559 ns 57403 ns 12270 * BM_PREPROCESSING/1/2 17524 ns 17466 ns 39982 * BM_PREPROCESSING/1/3 2608 ns 2599 ns 268399 * BM_PREPROCESSING/2/0 94198 ns 93926 ns 7470 * BM_PREPROCESSING/2/1 109196 ns 108899 ns 6459 * BM_PREPROCESSING/2/2 34098 ns 33986 ns 20576 * BM_PREPROCESSING/2/3 3231 ns 3221 ns 216606 * BM_PREPROCESSING/3/0 141532 ns 141132 ns 5030 * BM_PREPROCESSING/3/1 161199 ns 160745 ns 4387 * BM_PREPROCESSING/3/2 50663 ns 50535 ns 13619 * BM_PREPROCESSING/3/3 3967 ns 3955 ns 177005 * BM_PREPROCESSING/4/0 187032 ns 186486 ns 3706 * BM_PREPROCESSING/4/1 212872 ns 212264 ns 3304 * BM_PREPROCESSING/4/2 67649 ns 67476 ns 10128 * BM_PREPROCESSING/4/3 4728 ns 4713 ns 148547 * BM_PREPROCESSING/5/0 233874 ns 233188 ns 2954 * BM_PREPROCESSING/5/1 262798 ns 262052 ns 2680 * BM_PREPROCESSING/5/2 84592 ns 84368 ns 8203 * BM_PREPROCESSING/5/3 5472 ns 5455 ns 127784 * BM_PREPROCESSING/6/0 284777 ns 283911 ns 2468 * BM_PREPROCESSING/6/1 315631 ns 314726 ns 2233 * BM_PREPROCESSING/6/2 101200 ns 100931 ns 6802 * BM_PREPROCESSING/6/3 6152 ns 6133 ns 113951 * BM_PREPROCESSING/7/0 327207 ns 326153 ns 2112 * BM_PREPROCESSING/7/1 367510 ns 366410 ns 1915 * BM_PREPROCESSING/7/2 118574 ns 118250 ns 5795 * BM_PREPROCESSING/7/3 6956 ns 6935 ns 100783 * BM_PREPROCESSING/8/0 372603 ns 371470 ns 1880 * BM_PREPROCESSING/8/1 418882 ns 417625 ns 1685 * BM_PREPROCESSING/8/2 136155 ns 135777 ns 4986 * BM_PREPROCESSING/8/3 7734 ns 7711 ns 91581 * BM_PREPROCESSING/9/0 424795 ns 423464 ns 1657 * BM_PREPROCESSING/9/1 469073 ns 467687 ns 1506 * BM_PREPROCESSING/9/2 153170 ns 152737 ns 4519 * BM_PREPROCESSING/9/3 8393 ns 8363 ns 83603 * BM_PREPROCESSING/10/0 472440 ns 470926 ns 1489 * BM_PREPROCESSING/10/1 516984 ns 515480 ns 1000 * BM_PREPROCESSING/10/2 168802 ns 168348 ns 4097 * BM_PREPROCESSING/10/3 9127 ns 9100 ns 76913 * BM_PREPROCESSING/11/0 509690 ns 508113 ns 1360 * BM_PREPROCESSING/11/1 569076 ns 567390 ns 1310 * BM_PREPROCESSING/11/2 185678 ns 185165 ns 3729 * BM_PREPROCESSING/11/3 9789 ns 9760 ns 71342 * BM_PREPROCESSING/12/0 563858 ns 562108 ns 1270 * BM_PREPROCESSING/12/1 619656 ns 617791 ns 1198 * BM_PREPROCESSING/12/2 202882 ns 202316 ns 3406 * BM_PREPROCESSING/12/3 10610 ns 10579 ns 66287 * BM_PREPROCESSING/13/0 602944 ns 601094 ns 1167 * BM_PREPROCESSING/13/1 675401 ns 673293 ns 1107 * BM_PREPROCESSING/13/2 220677 ns 220051 ns 3131 * BM_PREPROCESSING/13/3 11301 ns 11265 ns 62022 * BM_PREPROCESSING/14/0 659495 ns 657375 ns 1071 * BM_PREPROCESSING/14/1 726551 ns 724295 ns 1024 * BM_PREPROCESSING/14/2 238595 ns 237922 ns 2901 * BM_PREPROCESSING/14/3 11941 ns 11906 ns 58788 * BM_PREPROCESSING/15/0 698377 ns 696134 ns 1014 * BM_PREPROCESSING/15/1 772532 ns 770217 ns 960 * BM_PREPROCESSING/15/2 253219 ns 252505 ns 2736 * BM_PREPROCESSING/15/3 12669 ns 12632 ns 55452 * BM_PREPROCESSING/16/0 742054 ns 739708 ns 936 * BM_PREPROCESSING/16/1 828029 ns 825484 ns 902 * BM_PREPROCESSING/16/2 272419 ns 271658 ns 2545 * BM_PREPROCESSING/16/3 13473 ns 13431 ns 52088 * BM_PREPROCESSING/17/0 794444 ns 791916 ns 891 * BM_PREPROCESSING/17/1 879429 ns 876704 ns 841 * BM_PREPROCESSING/17/2 290059 ns 289216 ns 2391 * BM_PREPROCESSING/17/3 14257 ns 14210 ns 49425 * BM_PREPROCESSING/18/0 852221 ns 849430 ns 839 * BM_PREPROCESSING/18/1 931121 ns 928308 ns 799 * BM_PREPROCESSING/18/2 307995 ns 307104 ns 2253 * BM_PREPROCESSING/18/3 14947 ns 14900 ns 46872 * BM_PREPROCESSING/19/0 888752 ns 885893 ns 781 * BM_PREPROCESSING/19/1 983398 ns 980285 ns 756 * BM_PREPROCESSING/19/2 325669 ns 324705 ns 2132 * BM_PREPROCESSING/19/3 15677 ns 15629 ns 44693 * BM_PREPROCESSING/20/0 933651 ns 930697 ns 746 * BM_PREPROCESSING/20/1 1033396 ns 1030235 ns 713 * BM_PREPROCESSING/20/2 342081 ns 341077 ns 2031 * BM_PREPROCESSING/20/3 16422 ns 16370 ns 42622 * BM_PREPROCESSING/21/0 982521 ns 979388 ns 706 * BM_PREPROCESSING/21/1 1085340 ns 1081926 ns 682 * BM_PREPROCESSING/21/2 360862 ns 359810 ns 1926 * BM_PREPROCESSING/21/3 17161 ns 17107 ns 40885 * BM_PREPROCESSING/22/0 1043560 ns 1040219 ns 678 * BM_PREPROCESSING/22/1 1137203 ns 1133687 ns 653 * BM_PREPROCESSING/22/2 377421 ns 376315 ns 1841 * BM_PREPROCESSING/22/3 17903 ns 17847 ns 38984 * BM_PREPROCESSING/23/0 1090097 ns 1086523 ns 650 * BM_PREPROCESSING/23/1 1199267 ns 1194231 ns 619 * BM_PREPROCESSING/23/2 395429 ns 394263 ns 1759 * BM_PREPROCESSING/23/3 18879 ns 18818 ns 37242 * BM_PREPROCESSING/24/0 1128638 ns 1125076 ns 629 * BM_PREPROCESSING/24/1 1239909 ns 1236019 ns 598 * BM_PREPROCESSING/24/2 414294 ns 413055 ns 1680 * BM_PREPROCESSING/24/3 19583 ns 19521 ns 35771 *******************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM; constexpr int kSampleRate = 16000; constexpr float kTenMilliSecVal = 0.01; constexpr unsigned int kStreamDelayMs = 0; constexpr effect_uuid_t kEffectUuids[] = { // agc uuid {0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // aec uuid {0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // ns uuid {0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // agc2 uuid {0x89f38e65, 0xd4d2, 0x4d64, 0xad0e, {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}}, }; constexpr size_t kNumEffectUuids = std::size(kEffectUuids); 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); // types of pre processing modules enum PreProcId { PREPROC_AGC, // Automatic Gain Control PREPROC_AEC, // Acoustic Echo Canceler PREPROC_NS, // Noise Suppressor PREPROC_AGC2, // Automatic Gain Control 2 PREPROC_NUM_EFFECTS }; int preProcCreateEffect(effect_handle_t* pEffectHandle, uint32_t effectType, effect_config_t* pConfig, int sessionId, int ioId) { if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&kEffectUuids[effectType], sessionId, ioId, pEffectHandle); status != 0) { ALOGE("Audio Preprocessing create returned an error = %d\n", status); return EXIT_FAILURE; } int reply = 0; uint32_t replySize = sizeof(reply); if (effectType == PREPROC_AEC) { if (int status = (**pEffectHandle) ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG_REVERSE, sizeof(effect_config_t), pConfig, &replySize, &reply); status != 0) { ALOGE("Set config reverse command returned an error = %d\n", status); return EXIT_FAILURE; } } if (int status = (**pEffectHandle) ->command(*pEffectHandle, EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t), pConfig, &replySize, &reply); status != 0) { ALOGE("Set config command returned an error = %d\n", status); return EXIT_FAILURE; } return reply; } int preProcSetConfigParam(effect_handle_t effectHandle, uint32_t paramType, uint32_t paramValue) { int reply = 0; uint32_t replySize = sizeof(reply); uint32_t paramData[2] = {paramType, paramValue}; effect_param_t* effectParam = (effect_param_t*)malloc(sizeof(*effectParam) + sizeof(paramData)); memcpy(&effectParam->data[0], ¶mData[0], sizeof(paramData)); effectParam->psize = sizeof(paramData[0]); (*effectHandle) ->command(effectHandle, EFFECT_CMD_SET_PARAM, sizeof(effect_param_t), effectParam, &replySize, &reply); free(effectParam); return reply; } short preProcGetShortVal(float paramValue) { return static_cast(paramValue * std::numeric_limits::max()); } static void BM_PREPROCESSING(benchmark::State& state) { const size_t chMask = kChMasks[state.range(0) - 1]; const size_t channelCount = audio_channel_count_from_in_mask(chMask); PreProcId effectType = (PreProcId)state.range(1); int32_t sessionId = 1; int32_t ioId = 1; effect_handle_t effectHandle = nullptr; 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_16_BIT; if (int status = preProcCreateEffect(&effectHandle, state.range(1), &config, sessionId, ioId); status != 0) { ALOGE("Create effect call returned error %i", status); return; } int reply = 0; uint32_t replySize = sizeof(reply); 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; } // Initialize input buffer with deterministic pseudo-random values const int frameLength = (int)(kSampleRate * kTenMilliSecVal); std::minstd_rand gen(chMask); std::uniform_real_distribution<> dis(-1.0f, 1.0f); std::vector in(frameLength * channelCount); for (auto& i : in) { i = preProcGetShortVal(dis(gen)); } std::vector farIn(frameLength * channelCount); for (auto& i : farIn) { i = preProcGetShortVal(dis(gen)); } std::vector out(frameLength * channelCount); // Run the test for (auto _ : state) { benchmark::DoNotOptimize(in.data()); benchmark::DoNotOptimize(out.data()); benchmark::DoNotOptimize(farIn.data()); audio_buffer_t inBuffer = {.frameCount = (size_t)frameLength, .s16 = in.data()}; audio_buffer_t outBuffer = {.frameCount = (size_t)frameLength, .s16 = out.data()}; audio_buffer_t farInBuffer = {.frameCount = (size_t)frameLength, .s16 = farIn.data()}; if (PREPROC_AEC == effectType) { if (int status = preProcSetConfigParam(effectHandle, AEC_PARAM_ECHO_DELAY, kStreamDelayMs); status != 0) { ALOGE("preProcSetConfigParam returned Error %d\n", status); return; } } if (int status = (*effectHandle)->process(effectHandle, &inBuffer, &outBuffer); status != 0) { ALOGE("\nError: Process i = %d returned with error %d\n", (int)state.range(1), status); return; } if (PREPROC_AEC == effectType) { if (int status = (*effectHandle)->process_reverse(effectHandle, &farInBuffer, &outBuffer); status != 0) { ALOGE("\nError: Process reverse i = %d returned with error %d\n", (int)state.range(1), status); return; } } } 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 preprocessingArgs(benchmark::internal::Benchmark* b) { for (int i = 1; i <= (int)kNumChMasks; i++) { for (int j = 0; j < (int)kNumEffectUuids; ++j) { b->Args({i, j}); } } } BENCHMARK(BM_PREPROCESSING)->Apply(preprocessingArgs); BENCHMARK_MAIN();