1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <benchmark/benchmark.h>
17 #include <climits>
18 #include <gtest/gtest.h>
19 #include "hdf_base.h"
20 #include "osal_mem.h"
21 #include "v1_0/iaudio_manager.h"
22
23 using namespace testing::ext;
24 using namespace std;
25
26 #define AUDIO_CHANNELCOUNT 2
27 #define AUDIO_SAMPLE_RATE_48K 48000
28 #define DEEP_BUFFER_RENDER_PERIOD_SIZE 4096
29 #define INT_32_MAX 0x7fffffff
30 #define PCM_16_BIT 16
31 #define PCM_8_BIT 8
32
33 namespace {
34 static const uint32_t g_audioAdapterNumMax = 5;
35 const int32_t AUDIO_ADAPTER_BUF_TEST = 1024;
36 const int32_t ITERATION_FREQUENCY = 100;
37 const int32_t REPETITION_FREQUENCY = 3;
38
39 class AudioAdapterBenchmarkTest : public benchmark::Fixture {
40 public:
41 struct IAudioManager *manager_ = nullptr;
42 struct IAudioAdapter *adapter_ = nullptr;
43 struct AudioAdapterDescriptor *adapterDescs_ = nullptr;
44 uint32_t renderId_ = 0;
45 uint32_t captureId_ = 0;
46 void SetUp(const ::benchmark::State &state);
47 void TearDown(const ::benchmark::State &state);
48 void InitAttrs(struct AudioSampleAttributes &attrs);
49 void InitDevDesc(struct AudioDeviceDescriptor &devDesc);
50 void AudioAdapterDescriptorFree(struct AudioAdapterDescriptor *dataBlock, bool freeSelf);
51 void ReleaseAdapterDescs(struct AudioAdapterDescriptor *descs, uint32_t descsLen);
52 };
53
AudioAdapterDescriptorFree(struct AudioAdapterDescriptor * dataBlock,bool freeSelf)54 void AudioAdapterBenchmarkTest::AudioAdapterDescriptorFree(struct AudioAdapterDescriptor *dataBlock, bool freeSelf)
55 {
56 if (dataBlock == nullptr) {
57 return;
58 }
59
60 if (dataBlock->adapterName != nullptr) {
61 OsalMemFree(dataBlock->adapterName);
62 dataBlock->adapterName = nullptr;
63 }
64
65 if (dataBlock->ports != nullptr) {
66 OsalMemFree(dataBlock->ports);
67 }
68
69 if (freeSelf) {
70 OsalMemFree(dataBlock);
71 }
72 }
73
ReleaseAdapterDescs(struct AudioAdapterDescriptor * descs,uint32_t descsLen)74 void AudioAdapterBenchmarkTest::ReleaseAdapterDescs(struct AudioAdapterDescriptor *descs, uint32_t descsLen)
75 {
76 if ((descs == nullptr) || (descsLen == 0)) {
77 return;
78 }
79
80 for (uint32_t i = 0; i < descsLen; i++) {
81 AudioAdapterDescriptorFree(&descs[i], false);
82 }
83 }
84
InitAttrs(struct AudioSampleAttributes & attrs)85 void AudioAdapterBenchmarkTest::InitAttrs(struct AudioSampleAttributes &attrs)
86 {
87 attrs.format = AUDIO_FORMAT_TYPE_PCM_16_BIT;
88 attrs.channelCount = AUDIO_CHANNELCOUNT;
89 attrs.sampleRate = AUDIO_SAMPLE_RATE_48K;
90 attrs.interleaved = 1;
91 attrs.type = AUDIO_IN_MEDIA;
92 attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
93 attrs.frameSize = PCM_16_BIT * attrs.channelCount / PCM_8_BIT;
94 attrs.isBigEndian = false;
95 attrs.isSignedData = true;
96 attrs.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (attrs.frameSize);
97 attrs.stopThreshold = INT_32_MAX;
98 }
99
InitDevDesc(struct AudioDeviceDescriptor & devDesc)100 void AudioAdapterBenchmarkTest::InitDevDesc(struct AudioDeviceDescriptor &devDesc)
101 {
102 ASSERT_NE(adapterDescs_, nullptr);
103 ASSERT_NE(adapterDescs_->ports, nullptr);
104 for (uint32_t index = 0; index < adapterDescs_->portsLen; index++) {
105 if (adapterDescs_->ports[index].dir == PORT_OUT) {
106 devDesc.portId = adapterDescs_->ports[index].portId;
107 return;
108 }
109 }
110 }
111
SetUp(const::benchmark::State & state)112 void AudioAdapterBenchmarkTest::SetUp(const ::benchmark::State &state)
113 {
114 uint32_t size = g_audioAdapterNumMax;
115 manager_ = IAudioManagerGet(false);
116 ASSERT_NE(manager_, nullptr);
117
118 adapterDescs_ = (struct AudioAdapterDescriptor *)OsalMemCalloc(
119 sizeof(struct AudioAdapterDescriptor) * (g_audioAdapterNumMax));
120 ASSERT_NE(adapterDescs_, nullptr);
121
122 ASSERT_EQ(HDF_SUCCESS, manager_->GetAllAdapters(manager_, adapterDescs_, &size));
123 if (size > g_audioAdapterNumMax) {
124 ReleaseAdapterDescs(adapterDescs_, g_audioAdapterNumMax);
125 ASSERT_LT(size, g_audioAdapterNumMax);
126 }
127
128 if (manager_->LoadAdapter(manager_, &adapterDescs_[0], &adapter_) != HDF_SUCCESS) {
129 ReleaseAdapterDescs(adapterDescs_, g_audioAdapterNumMax);
130 ASSERT_TRUE(false);
131 }
132
133 if (adapter_ == nullptr) {
134 ReleaseAdapterDescs(adapterDescs_, g_audioAdapterNumMax);
135 ASSERT_TRUE(false);
136 }
137 }
138
TearDown(const::benchmark::State & state)139 void AudioAdapterBenchmarkTest::TearDown(const ::benchmark::State &state)
140 {
141 ASSERT_NE(manager_, nullptr);
142 ASSERT_NE(adapter_, nullptr);
143
144 manager_->UnloadAdapter(manager_, adapterDescs_[0].adapterName);
145 ReleaseAdapterDescs(adapterDescs_, g_audioAdapterNumMax);
146 adapter_ = nullptr;
147 IAudioManagerRelease(manager_, false);
148 manager_ = nullptr;
149 }
150
BENCHMARK_F(AudioAdapterBenchmarkTest,InitAllPorts)151 BENCHMARK_F(AudioAdapterBenchmarkTest, InitAllPorts)(benchmark::State &state)
152 {
153 ASSERT_NE(adapter_, nullptr);
154 int32_t ret;
155 for (auto _ : state) {
156 ret = adapter_->InitAllPorts(adapter_);
157 EXPECT_EQ(HDF_SUCCESS, ret);
158 }
159 }
160
161 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, InitAllPorts)->
162 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
163
BENCHMARK_F(AudioAdapterBenchmarkTest,CreateRenderAndDestroyRender)164 BENCHMARK_F(AudioAdapterBenchmarkTest, CreateRenderAndDestroyRender)(benchmark::State &state)
165 {
166 ASSERT_NE(adapter_, nullptr);
167 int32_t ret;
168 struct IAudioRender *render = nullptr;
169 struct AudioDeviceDescriptor devicedesc = {};
170 struct AudioSampleAttributes attrs = {};
171 InitDevDesc(devicedesc);
172 devicedesc.desc = const_cast<char*>("primary");
173 devicedesc.pins = PIN_OUT_SPEAKER;
174 InitAttrs(attrs);
175 attrs.silenceThreshold = 0;
176 attrs.streamId = 0;
177
178 for (auto _ : state) {
179 ret = adapter_->CreateRender(adapter_, &devicedesc, &attrs, &render, &renderId_);
180 if (ret != HDF_SUCCESS) {
181 attrs.format = AUDIO_FORMAT_TYPE_PCM_32_BIT;
182 ASSERT_EQ(HDF_SUCCESS, adapter_->CreateRender(adapter_, &devicedesc, &attrs, &render, &renderId_));
183 }
184 ret = adapter_->DestroyRender(adapter_, renderId_);
185 EXPECT_EQ(HDF_SUCCESS, ret);
186 }
187 }
188
189 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, CreateRenderAndDestroyRender)->
190 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
191
BENCHMARK_F(AudioAdapterBenchmarkTest,CreateCaptureAndDestroyCapture)192 BENCHMARK_F(AudioAdapterBenchmarkTest, CreateCaptureAndDestroyCapture)(benchmark::State &state)
193 {
194 ASSERT_NE(adapter_, nullptr);
195 int32_t ret;
196 struct IAudioCapture *capture = nullptr;
197 struct AudioDeviceDescriptor devicedesc = {};
198 struct AudioSampleAttributes attrs = {};
199 InitDevDesc(devicedesc);
200 devicedesc.desc = const_cast<char*>("primary");
201 devicedesc.pins = PIN_IN_MIC;
202 InitAttrs(attrs);
203 attrs.silenceThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE;
204
205 for (auto _ : state) {
206 ret = adapter_->CreateCapture(adapter_, &devicedesc, &attrs, &capture, &captureId_);
207 if (ret != HDF_SUCCESS) {
208 attrs.format = AUDIO_FORMAT_TYPE_PCM_32_BIT;
209 ASSERT_EQ(HDF_SUCCESS, adapter_->CreateCapture(adapter_, &devicedesc, &attrs, &capture, &captureId_));
210 }
211 ret = adapter_->DestroyCapture(adapter_, captureId_);
212 EXPECT_EQ(HDF_SUCCESS, ret);
213 }
214 }
215
216 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, CreateCaptureAndDestroyCapture)->
217 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
218
BENCHMARK_F(AudioAdapterBenchmarkTest,GetPortCapability)219 BENCHMARK_F(AudioAdapterBenchmarkTest, GetPortCapability)(benchmark::State &state)
220 {
221 ASSERT_NE(adapter_, nullptr);
222 int32_t ret;
223 struct AudioPort port = {};
224 struct AudioPortCapability capability = {};
225 port.dir = PORT_OUT;
226 port.portId = 0;
227 port.portName = const_cast<char*>("primary");
228
229 for (auto _ : state) {
230 ret = adapter_->GetPortCapability(adapter_, &port, &capability);
231 ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT);
232 }
233 }
234
235 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, GetPortCapability)->
236 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
237
BENCHMARK_F(AudioAdapterBenchmarkTest,SetPassthroughMode)238 BENCHMARK_F(AudioAdapterBenchmarkTest, SetPassthroughMode)(benchmark::State &state)
239 {
240 ASSERT_NE(adapter_, nullptr);
241 int32_t ret;
242 struct AudioPort port = {};
243 port.dir = PORT_OUT;
244 port.portId = 0;
245 port.portName = const_cast<char*>("primary");
246 enum AudioPortPassthroughMode mode = PORT_PASSTHROUGH_LPCM;
247
248 for (auto _ : state) {
249 ret = adapter_->SetPassthroughMode(adapter_, &port, mode);
250 ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_FAILURE);
251 }
252 }
253
254 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, SetPassthroughMode)->
255 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
256
BENCHMARK_F(AudioAdapterBenchmarkTest,GetPassthroughMode)257 BENCHMARK_F(AudioAdapterBenchmarkTest, GetPassthroughMode)(benchmark::State &state)
258 {
259 ASSERT_NE(adapter_, nullptr);
260 int32_t ret;
261 struct AudioPort port = {};
262 port.dir = PORT_OUT;
263 port.portId = 0;
264 port.portName = const_cast<char*>("primary");
265 enum AudioPortPassthroughMode mode;
266
267 for (auto _ : state) {
268 ret = adapter_->GetPassthroughMode(adapter_, &port, &mode);
269 ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_FAILURE);
270 }
271 }
272
273 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, GetPassthroughMode)->
274 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
275
BENCHMARK_F(AudioAdapterBenchmarkTest,GetDeviceStatus)276 BENCHMARK_F(AudioAdapterBenchmarkTest, GetDeviceStatus)(benchmark::State &state)
277 {
278 ASSERT_NE(adapter_, nullptr);
279 int32_t ret;
280 struct AudioDeviceStatus status = {};
281
282 for (auto _ : state) {
283 ret = adapter_->GetDeviceStatus(adapter_, &status);
284 EXPECT_EQ(HDF_SUCCESS, ret);
285 }
286 }
287
288 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, GetDeviceStatus)->
289 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
290
BENCHMARK_F(AudioAdapterBenchmarkTest,GetMicMute)291 BENCHMARK_F(AudioAdapterBenchmarkTest, GetMicMute)(benchmark::State &state)
292 {
293 ASSERT_NE(adapter_, nullptr);
294 int32_t ret;
295 bool mute = false;
296
297 for (auto _ : state) {
298 ret = adapter_->GetMicMute(adapter_, &mute);
299 ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT);
300 }
301 }
302
303 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, GetMicMute)->
304 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
305
BENCHMARK_F(AudioAdapterBenchmarkTest,SetVoiceVolume)306 BENCHMARK_F(AudioAdapterBenchmarkTest, SetVoiceVolume)(benchmark::State &state)
307 {
308 ASSERT_NE(adapter_, nullptr);
309 int32_t ret;
310 float volume = 0;
311
312 for (auto _ : state) {
313 ret = adapter_->SetVoiceVolume(adapter_, volume);
314 ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT);
315 }
316 }
317
318 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, SetVoiceVolume)->
319 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
320
BENCHMARK_F(AudioAdapterBenchmarkTest,SetExtraParams)321 BENCHMARK_F(AudioAdapterBenchmarkTest, SetExtraParams)(benchmark::State &state)
322 {
323 ASSERT_NE(adapter_, nullptr);
324 int32_t ret;
325 enum AudioExtParamKey key = AUDIO_EXT_PARAM_KEY_LOWPOWER;
326 char condition[AUDIO_ADAPTER_BUF_TEST];
327 const char *value = "sup_sampling_rates=4800;sup_channels=1;sup_formats=2;";
328
329 for (auto _ : state) {
330 ret = adapter_->SetExtraParams(adapter_, key, condition, value);
331 ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_ERR_NOT_SUPPORT);
332 }
333 }
334
335 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, SetExtraParams)->
336 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
337
BENCHMARK_F(AudioAdapterBenchmarkTest,GetExtraParams)338 BENCHMARK_F(AudioAdapterBenchmarkTest, GetExtraParams)(benchmark::State &state)
339 {
340 ASSERT_NE(adapter_, nullptr);
341 int32_t ret;
342 enum AudioExtParamKey key = AUDIO_EXT_PARAM_KEY_NONE;
343 char condition[AUDIO_ADAPTER_BUF_TEST];
344 char value[AUDIO_ADAPTER_BUF_TEST] = "sup_sampling_rates=4800;sup_channels=1;sup_formats=2;";
345 uint32_t valueLen = AUDIO_ADAPTER_BUF_TEST;
346
347 for (auto _ : state) {
348 ret = adapter_->GetExtraParams(adapter_, key, condition, value, valueLen);
349 EXPECT_NE(HDF_SUCCESS, ret);
350 }
351 }
352
353 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, GetExtraParams)->
354 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
355
BENCHMARK_F(AudioAdapterBenchmarkTest,UpdateAudioRoute)356 BENCHMARK_F(AudioAdapterBenchmarkTest, UpdateAudioRoute)(benchmark::State &state)
357 {
358 ASSERT_NE(adapter_, nullptr);
359 int32_t ret;
360 struct AudioRoute route = {};
361 int32_t routeHandle = 0;
362
363 for (auto _ : state) {
364 ret = adapter_->UpdateAudioRoute(adapter_, &route, &routeHandle);
365 EXPECT_NE(HDF_SUCCESS, ret);
366 }
367 }
368
369 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, UpdateAudioRoute)->
370 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
371
BENCHMARK_F(AudioAdapterBenchmarkTest,ReleaseAudioRoute)372 BENCHMARK_F(AudioAdapterBenchmarkTest, ReleaseAudioRoute)(benchmark::State &state)
373 {
374 ASSERT_NE(adapter_, nullptr);
375 int32_t ret;
376 int32_t routeHandle = 0;
377
378 for (auto _ : state) {
379 ret = adapter_->ReleaseAudioRoute(adapter_, routeHandle);
380 EXPECT_NE(HDF_SUCCESS, ret);
381 }
382 }
383
384 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, ReleaseAudioRoute)->
385 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
386
BENCHMARK_F(AudioAdapterBenchmarkTest,RegExtraParamObserver)387 BENCHMARK_F(AudioAdapterBenchmarkTest, RegExtraParamObserver)(benchmark::State &state)
388 {
389 ASSERT_NE(adapter_, nullptr);
390 int32_t ret;
391 int8_t cookie = 0;
392 struct IAudioCallback *audioCallback = nullptr;
393
394 for (auto _ : state) {
395 ret = adapter_->RegExtraParamObserver(adapter_, audioCallback, cookie);
396 ASSERT_TRUE(ret == HDF_SUCCESS || ret == HDF_ERR_INVALID_PARAM);
397 }
398 }
399
400 BENCHMARK_REGISTER_F(AudioAdapterBenchmarkTest, RegExtraParamObserver)->
401 Iterations(ITERATION_FREQUENCY)->Repetitions(REPETITION_FREQUENCY)->ReportAggregatesOnly();
402 }
403