blob: bdb66d89da20e763c8118a86100f4b57de4700e4 [file] [log] [blame]
/*
* 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();