323 lines
15 KiB
C++
323 lines
15 KiB
C++
/*
|
|
* 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 <audio_effects/effect_aec.h>
|
|
#include <audio_effects/effect_agc.h>
|
|
#include <array>
|
|
#include <climits>
|
|
#include <cstdlib>
|
|
#include <random>
|
|
#include <vector>
|
|
#include <audio_effects/effect_agc2.h>
|
|
#include <audio_effects/effect_ns.h>
|
|
#include <benchmark/benchmark.h>
|
|
#include <hardware/audio_effect.h>
|
|
#include <log/log.h>
|
|
#include <sys/stat.h>
|
|
#include <system/audio.h>
|
|
|
|
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<short>(paramValue * std::numeric_limits<short>::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<short> in(frameLength * channelCount);
|
|
for (auto& i : in) {
|
|
i = preProcGetShortVal(dis(gen));
|
|
}
|
|
std::vector<short> farIn(frameLength * channelCount);
|
|
for (auto& i : farIn) {
|
|
i = preProcGetShortVal(dis(gen));
|
|
}
|
|
std::vector<short> 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();
|