1 /*
2 * Copyright (c) 2023-2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "OhAudioCapturerLowlatencyTest"
17 #endif
18
19 #include <ostream>
20 #include <sstream>
21 #include <iostream>
22 #include <string>
23 #include <map>
24 #include <cstdint>
25 #include <cstdio>
26 #include <cstring>
27 #include "native_audiostreambuilder.h"
28 #include <native_audiocapturer.h>
29 #include <thread>
30 #include <chrono>
31 #include <securec.h>
32 #include "audio_info.h"
33 #include "audio_system_manager.h"
34 #include "audio_errors.h"
35 #include "audio_common_log.h"
36 using namespace std;
37
38 namespace OHOS {
39 namespace AudioStandard {
40 namespace {
41 enum OperationCode : int32_t {
42 INVALID_OPERATION = -1,
43 RELEASE_SPK_OH = 1,
44 START_SPK_OH = 2,
45 STOP_SPK_OH = 3,
46 START_LOOP_TEST = 4,
47 END_LOOP_TEST = 5,
48 INIT_LOCAL_MIC_OH = 6,
49 INIT_REMOTE_MIC_OH = 7,
50 START_MIC_OH = 8,
51 PAUSE_MIC_OH = 9,
52 STOP_MIC_OH = 10,
53 RELEASE_MIC_OH = 11,
54 EXIT_INTERACTIVE_TEST = 20,
55 };
56
57 enum AudioOHTestType : int32_t {
58 INVALID_OH_TEST = 0,
59 INTERACTIVE_RUN_MIC_TEST = 1,
60 INTERACTIVE_RUN_LOOP = 2,
61 EXIT_OH_TEST = 7,
62 };
63 static constexpr size_t CACHE_BUFFER_SIZE = 960;
64 int64_t g_stampTime = 0;
65 OperationCode g_optCode = INVALID_OPERATION;
66 }
67
68 class AudioNdkTest;
69
70 shared_ptr<AudioNdkTest> g_audioNdkTest = nullptr;
71 string g_spkfilePath = "";
72 const string MIC_FILE_PATH = "/data/data/mic_oh.pcm";
73 FILE *g_spkWavFile = nullptr;
74 FILE *g_micPcmFile = nullptr;
75 OH_AudioStreamBuilder* builder;
76 OH_AudioCapturer* audioCapturer;
77 OH_AudioRenderer* audioRenderer;
78 OH_AudioStream_Result ret;
79 int32_t g_latencyMode = 1;
80 static constexpr int64_t SECOND_TO_NANOSECOND = 1000000000;
81 int32_t g_loopCount = -1; // for loop
82 unique_ptr<uint8_t[]> g_byteBuffer = nullptr;
83 BufferDesc g_cacheBuffer = {nullptr, 0, 0};
84
85 string CallStartSpk();
86 string CallStopSpk();
87 string CallReleaseSpk();
88 string ConfigMicTest(bool isRemote);
89 string CallStartMic();
90 string CallPauseMic();
91 string CallStopMic();
92 string CallReleaseMic();
93 using CallTestOperationFunc = string (*)();
94
95 map<int32_t, string> g_audioNdkTestType = {
96 {INTERACTIVE_RUN_MIC_TEST, "Interactive run mic oh test"},
97 {INTERACTIVE_RUN_LOOP, "Roundtrip latency test"},
98 {EXIT_OH_TEST, "Exit audio oh test"},
99 };
100
101 map<int32_t, string> g_interactiveOptStrMap = {
102 {START_SPK_OH, "call start spk oh"},
103 {STOP_SPK_OH, "call stop spk oh"},
104 {RELEASE_SPK_OH, "release spk oh"},
105 {START_LOOP_TEST, "start loop"},
106 {END_LOOP_TEST, "end loop"},
107 {INIT_LOCAL_MIC_OH, "call local mic init oh"},
108 {INIT_REMOTE_MIC_OH, "call remote mic init oh"},
109 {START_MIC_OH, "call start mic oh"},
110 {PAUSE_MIC_OH, "call pause mic oh"},
111 {STOP_MIC_OH, "call stop mic oh"},
112 {RELEASE_MIC_OH, "release mic oh"},
113 {EXIT_INTERACTIVE_TEST, "exit interactive run test"},
114 };
115
116 map<int32_t, CallTestOperationFunc> g_interactiveOptFuncMap = {
117 {START_SPK_OH, CallStartSpk},
118 {STOP_SPK_OH, CallStopSpk},
119 {RELEASE_SPK_OH, CallReleaseSpk},
120 {START_MIC_OH, CallStartMic},
121 {PAUSE_MIC_OH, CallPauseMic},
122 {STOP_MIC_OH, CallStopMic},
123 {RELEASE_MIC_OH, CallReleaseMic}
124 };
125
126 class AudioNdkTest {
127 public:
128 AudioNdkTest() = default;
129 ~AudioNdkTest() = default;
130
131 int32_t InitSpk(int32_t loopCount, bool isRemote);
132 bool StartSpk();
133 bool StopSpk();
134 bool ReleaseSpk();
135 int32_t InitMic(bool isRemote);
136 bool StartMic();
137 bool PauseMic();
138 bool StopMic();
139 bool ReleaseMic();
140 void SelectDevice(DeviceRole deviceRole);
141 };
142
InitSignalBuffer(void * signalSoundBuffer,int32_t bufferLen)143 void InitSignalBuffer(void* signalSoundBuffer, int32_t bufferLen)
144 {
145 int ret = memset_s(signalSoundBuffer, bufferLen, 0, bufferLen);
146 if (ret != EOK) {
147 return;
148 }
149 const int channels = 2; // 2 channels
150 const int samplePerChannel = 96 / channels; // 96 for 1ms
151 int16_t *signalData = static_cast<int16_t *>(signalSoundBuffer);
152 int16_t bound = 10;
153 for (int idx = 0; idx < samplePerChannel; idx++) {
154 signalData[channels * idx] = bound + static_cast<int16_t>(sinf(2.0f * static_cast<float>(M_PI) * idx /
155 samplePerChannel) * (SHRT_MAX - bound));
156 for (int c = 1; c < channels; c++) {
157 signalData[channels * idx + c] = signalData[channels * idx];
158 }
159 }
160 }
161
AudioRendererOnWriteData(OH_AudioRenderer * renderer,void * userData,void * buffer,int32_t bufferLen)162 static int32_t AudioRendererOnWriteData(OH_AudioRenderer* renderer,
163 void* userData,
164 void* buffer,
165 int32_t bufferLen)
166 {
167 g_loopCount++;
168 int32_t periodCount = g_loopCount % 400; // 400 * 0.005 = 2s
169 if (periodCount == 0) {
170 InitSignalBuffer(buffer, bufferLen); // set signal data
171 int64_t temp = ClockTime::GetCurNano() - g_stampTime;
172 std::cout << "client read-write latency:" << (temp / AUDIO_MS_PER_SECOND) << " us" << std::endl;
173 return 0;
174 }
175 int32_t keepQuiteHold = 50;
176 if (periodCount > keepQuiteHold) {
177 return 0;
178 }
179 // copy mic data in the cache buffer
180 int ret = memcpy_s(buffer, bufferLen, static_cast<void *>(g_cacheBuffer.buffer), g_cacheBuffer.bufLength);
181 if (ret != EOK) {
182 AUDIO_WARNING_LOG("memcpy_s failed.");
183 }
184 return 0;
185 }
186
AudioCapturerOnReadData(OH_AudioCapturer * capturer,void * userData,void * buffer,int32_t bufferLen)187 static int32_t AudioCapturerOnReadData(OH_AudioCapturer* capturer,
188 void* userData,
189 void* buffer,
190 int32_t bufferLen)
191 {
192 if (g_optCode == START_LOOP_TEST) {
193 int32_t cnt = fwrite(buffer, 1, bufferLen, g_micPcmFile);
194 CHECK_AND_RETURN_RET_LOG(cnt == bufferLen, ERR_WRITE_FAILED,
195 "%{public}s fwrite fail, cnt %{public}d, bufLength %{public}d.", __func__, cnt, bufferLen);
196 int ret = memcpy_s(static_cast<void *>(g_cacheBuffer.buffer), bufferLen, buffer, bufferLen);
197 if (ret != EOK) {
198 AUDIO_WARNING_LOG("memcpy_s failed.");
199 }
200 g_stampTime = ClockTime::GetCurNano();
201 return 0;
202 }
203
204 size_t count = 1;
205 if (fwrite(buffer, bufferLen, count, g_micPcmFile) != count) {
206 cout <<"buffer fwrite err";
207 }
208 return 0;
209 }
210
211
InitSpk(int32_t loopCount,bool isRemote)212 int32_t AudioNdkTest::InitSpk(int32_t loopCount, bool isRemote)
213 {
214 if (loopCount < 0) {
215 g_loopCount = 1; // loop once
216 } else if (loopCount == 0) {
217 g_loopCount = -1; // infinite loop
218 } else {
219 g_loopCount = loopCount;
220 }
221
222 if (isRemote) {
223 SelectDevice(OUTPUT_DEVICE);
224 }
225
226 OH_AudioStream_Type type = AUDIOSTREAM_TYPE_RENDERER;
227 ret = OH_AudioStreamBuilder_Create(&builder, type);
228 cout << "createcallback ret: " << ret << endl;
229 // 2. set params and callbacks
230 OH_AudioStreamBuilder_SetSamplingRate(builder, SAMPLE_RATE_48000);
231 OH_AudioStreamBuilder_SetChannelCount(builder, STEREO);
232 OH_AudioStreamBuilder_SetLatencyMode(builder, (OH_AudioStream_LatencyMode)g_latencyMode);
233
234 OH_AudioRenderer_Callbacks callbacks;
235 callbacks.OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData;
236 ret = OH_AudioStreamBuilder_SetRendererCallback(builder, callbacks, nullptr);
237 cout << "setcallback ret: " << ret << endl;
238 // 3. create OH_AudioRenderer
239 ret = OH_AudioStreamBuilder_GenerateRenderer(builder, &audioRenderer);
240 cout << "create renderer client, ret: " << ret << endl;
241 return SUCCESS;
242 }
243
ReleaseSpk()244 bool AudioNdkTest::ReleaseSpk()
245 {
246 if (!audioRenderer) {
247 ret = OH_AudioRenderer_Release(audioRenderer);
248 cout << "Renderer release ret: " << ret << endl;
249 }
250
251 if (!builder) {
252 ret = OH_AudioStreamBuilder_Destroy(builder);
253 cout << "Renderer destroy builder ret: " << ret << endl;
254 }
255 return true;
256 }
257
StartSpk()258 bool AudioNdkTest::StartSpk()
259 {
260 ret = OH_AudioRenderer_Start(audioRenderer);
261 cout << "Renderer start ret: " << ret << endl;
262 return true;
263 }
264
StopSpk()265 bool AudioNdkTest::StopSpk()
266 {
267 ret = OH_AudioRenderer_Stop(audioRenderer);
268 cout << "Renderer stop ret: " << ret << endl;
269 return true;
270 }
271
InitMic(bool isRemote)272 int32_t AudioNdkTest::InitMic(bool isRemote)
273 {
274 if (isRemote) {
275 SelectDevice(INPUT_DEVICE);
276 }
277 // 1. create
278 OH_AudioStream_Type type = AUDIOSTREAM_TYPE_CAPTURER;
279 ret = OH_AudioStreamBuilder_Create(&builder, type);
280 cout <<"create capturer builder: " << ret << endl;
281
282 // 2. set params and callbacks
283 OH_AudioStreamBuilder_SetSamplingRate(builder, SAMPLE_RATE_48000);
284 OH_AudioStreamBuilder_SetChannelCount(builder, STEREO);
285 OH_AudioStreamBuilder_SetLatencyMode(builder, (OH_AudioStream_LatencyMode)g_latencyMode);
286
287 OH_AudioCapturer_Callbacks callbacks;
288 callbacks.OH_AudioCapturer_OnReadData = AudioCapturerOnReadData;
289 ret = OH_AudioStreamBuilder_SetCapturerCallback(builder, callbacks, nullptr);
290 cout << "setcallback: " << ret << endl;
291
292 // 3. create OH_AudioCapturer
293 ret = OH_AudioStreamBuilder_GenerateCapturer(builder, &audioCapturer);
294 cout << "create capturer client, ret: " << ret << endl;
295
296 return SUCCESS;
297 }
298
StartMic()299 bool AudioNdkTest::StartMic()
300 {
301 ret = OH_AudioCapturer_Start(audioCapturer);
302 cout << "start ret: " << ret << endl;
303 return true;
304 }
305
PauseMic()306 bool AudioNdkTest::PauseMic()
307 {
308 ret = OH_AudioCapturer_Pause(audioCapturer);
309 cout << "pause ret: " << ret << endl;
310 return true;
311 }
312
StopMic()313 bool AudioNdkTest::StopMic()
314 {
315 ret = OH_AudioCapturer_Stop(audioCapturer);
316 cout << "stop ret: " << ret << endl;
317 return true;
318 }
319
ReleaseMic()320 bool AudioNdkTest::ReleaseMic()
321 {
322 if (!audioCapturer) {
323 ret = OH_AudioCapturer_Release(audioCapturer);
324 cout << "release ret: " << ret << endl;
325 }
326
327 if (!builder) {
328 ret = OH_AudioStreamBuilder_Destroy(builder);
329 cout << "destroy builder ret: " << ret << endl;
330 }
331 return true;
332 }
333
SelectDevice(DeviceRole deviceRole)334 void AudioNdkTest::SelectDevice(DeviceRole deviceRole)
335 {
336 AudioSystemManager *manager = AudioSystemManager::GetInstance();
337 if (manager == nullptr) {
338 cout << "Get AudioSystemManager failed" << endl;
339 return;
340 }
341
342 vector<std::shared_ptr<AudioDeviceDescriptor>> devices;
343 if (deviceRole == OUTPUT_DEVICE) {
344 devices = manager->GetDevices(DISTRIBUTED_OUTPUT_DEVICES_FLAG);
345 } else {
346 devices = manager->GetDevices(DISTRIBUTED_INPUT_DEVICES_FLAG);
347 }
348 if (devices.size() != 1) {
349 cout << "GetDevices failed, unsupported size:" << devices.size() << endl;
350 return;
351 }
352 cout << "using device:" << devices[0]->networkId_ << endl;
353
354 int32_t ret = 0;
355 if (deviceRole == OUTPUT_DEVICE) {
356 sptr<AudioRendererFilter> filter = new AudioRendererFilter();
357 filter->uid = getuid();
358 filter->rendererInfo.rendererFlags = STREAM_FLAG_FAST;
359 ret = manager->SelectOutputDevice(filter, devices);
360 } else {
361 sptr<AudioCapturerFilter> filter = new AudioCapturerFilter();
362 filter->uid = getuid();
363 filter->capturerInfo.sourceType = SOURCE_TYPE_MIC;
364 filter->capturerInfo.capturerFlags = STREAM_FLAG_FAST;
365 ret = manager->SelectInputDevice(filter, devices);
366 }
367
368 if (ret == SUCCESS) {
369 cout << "SelectDevice seccess" << endl;
370 } else {
371 cout << "SelectDevice failed, ret:" << ret << endl;
372 }
373 }
374
OpenSpkFile()375 bool OpenSpkFile()
376 {
377 if (g_spkWavFile != nullptr) {
378 AUDIO_ERR_LOG("Spk file has been opened, g_spkfilePath %{public}s", g_spkfilePath.c_str());
379 return true;
380 }
381
382 char path[PATH_MAX] = { 0x00 };
383 if ((strlen(g_spkfilePath.c_str()) > PATH_MAX) || (realpath(g_spkfilePath.c_str(), path) == nullptr)) {
384 return false;
385 }
386 AUDIO_INFO_LOG("spk path = %{public}s", path);
387 g_spkWavFile = fopen(path, "rb");
388 if (g_spkWavFile == nullptr) {
389 AUDIO_ERR_LOG("Unable to open wave file");
390 return false;
391 }
392 return true;
393 }
394
CloseSpkFile()395 void CloseSpkFile()
396 {
397 if (g_spkWavFile != nullptr) {
398 fclose(g_spkWavFile);
399 g_spkWavFile = nullptr;
400 }
401 }
402
OpenMicFile()403 bool OpenMicFile()
404 {
405 if (g_micPcmFile != nullptr) {
406 AUDIO_ERR_LOG("Mic file has been opened, MIC_FILE_PATH %{public}s", MIC_FILE_PATH.c_str());
407 return true;
408 }
409
410 AUDIO_INFO_LOG("mic path = %{public}s", MIC_FILE_PATH.c_str());
411 g_micPcmFile = fopen(MIC_FILE_PATH.c_str(), "ab+");
412 if (g_micPcmFile == nullptr) {
413 AUDIO_ERR_LOG("Unable to open wave file");
414 return false;
415 }
416 return true;
417 }
418
CloseMicFile()419 void CloseMicFile()
420 {
421 if (g_micPcmFile != nullptr) {
422 fclose(g_micPcmFile);
423 g_micPcmFile = nullptr;
424 }
425 }
426
PrintInteractiveUsage()427 void PrintInteractiveUsage()
428 {
429 cout << endl << "======================= InteractiveRunTestSelect ============================" << endl;
430 cout << "You can respond to instructions for corresponding option:" << endl;
431 for (auto it = g_interactiveOptStrMap.begin(); it != g_interactiveOptStrMap.end(); it ++) {
432 cout << "\t enter " << it->first << " : " << it->second << endl;
433 }
434 }
435
PrintNdkTestUsage()436 void PrintNdkTestUsage()
437 {
438 cout << endl << "========================== NdkTestSelect ================================" << endl;
439 cout << "You can respond to instructions for corresponding test:" << endl;
440 for (auto it = g_audioNdkTestType.begin(); it != g_audioNdkTestType.end(); it ++) {
441 cout << it->first << ". " << it->second << endl;
442 }
443 }
444
GetUserInput()445 int32_t GetUserInput()
446 {
447 int32_t res = -1;
448 size_t count = 3;
449 cout << ">>";
450 cin >> res;
451 while (cin.fail() && count-- > 0) {
452 cin.clear();
453 cin.ignore();
454 cout << "invalid input, not a number! Please retry with a number." << endl;
455 cout << ">>";
456 cin >> res;
457 }
458 return res;
459 }
460
AutoRunMic()461 void AutoRunMic()
462 {
463 cout << "Auto run mic oh test enter, please input recordTimeS:" << endl;
464 int32_t recordTimeS = GetUserInput();
465 if (!OpenMicFile()) {
466 cout << "open mic file path failed!" << endl;
467 return;
468 }
469
470 if (g_audioNdkTest->InitMic(false) != SUCCESS) {
471 cout << "Mic init failed!" << endl;
472 return;
473 }
474
475 do {
476 if (!g_audioNdkTest->StartMic()) {
477 cout << "Mic start failed!" << endl;
478 break;
479 }
480
481 cout << "wait " << recordTimeS << "s for capture frame..." << endl;
482 ClockTime::RelativeSleep(recordTimeS * SECOND_TO_NANOSECOND);
483 cout << "AutoRunMic end" << endl;
484
485 if (!g_audioNdkTest->StopMic()) {
486 cout << "Mic stop failed!" << endl;
487 break;
488 }
489 } while (false);
490
491 if (!g_audioNdkTest->ReleaseMic()) {
492 cout << "Mic release failed!" << endl;
493 }
494 CloseMicFile();
495 }
496
ConfigMicTest(bool isRemote)497 string ConfigMicTest(bool isRemote)
498 {
499 if (!OpenMicFile()) {
500 cout << "Open mic file path failed!" << endl;
501 return "Open mic pcm file fail";
502 }
503
504 int32_t ret = g_audioNdkTest->InitMic(isRemote);
505 if (ret != SUCCESS) {
506 return "Mic init failed";
507 }
508 return "Mic init SUCCESS";
509 }
510
CallStartSpk()511 string CallStartSpk()
512 {
513 if (!g_audioNdkTest->StartSpk()) {
514 return "Spk start failed";
515 }
516 return "Spk start SUCCESS";
517 }
518
CallStopSpk()519 string CallStopSpk()
520 {
521 if (!g_audioNdkTest->StopSpk()) {
522 return "Spk stop failed";
523 }
524 return "Spk stop SUCCESS";
525 }
526
CallReleaseSpk()527 string CallReleaseSpk()
528 {
529 if (!g_audioNdkTest->ReleaseSpk()) {
530 return "Spk release failed";
531 }
532 CloseSpkFile();
533 return "Spk release SUCCESS";
534 }
535
CallStartMic()536 string CallStartMic()
537 {
538 if (!g_audioNdkTest->StartMic()) {
539 return "Mic start failed";
540 }
541 return "Mic start SUCCESS";
542 }
543
CallPauseMic()544 string CallPauseMic()
545 {
546 if (!g_audioNdkTest->PauseMic()) {
547 return "Mic pause failed";
548 }
549 return "Mic pause SUCCESS";
550 }
551
CallStopMic()552 string CallStopMic()
553 {
554 if (!g_audioNdkTest->StopMic()) {
555 return "Mic stop failed";
556 }
557 return "Mic stop SUCCESS";
558 }
559
CallReleaseMic()560 string CallReleaseMic()
561 {
562 if (!g_audioNdkTest->ReleaseMic()) {
563 return "Mic release failed";
564 }
565 CloseMicFile();
566 return "Mic release SUCCESS";
567 }
568
StartLoopTest()569 string StartLoopTest()
570 {
571 cout << ConfigMicTest(false) << endl;
572 cout << CallStartMic() << endl;
573
574 int32_t ret = g_audioNdkTest->InitSpk(0, false);
575 if (ret != SUCCESS) {
576 CallReleaseMic();
577 return "init spk failed";
578 } else {
579 std::cout << "init spk success" << endl;
580 }
581
582 cout << CallStartSpk() << endl;
583 return "StartLoopTest success!";
584 }
585
EndLoopTest()586 string EndLoopTest()
587 {
588 cout << CallStopSpk() << endl;
589 cout << CallReleaseSpk() << endl;
590 cout << CallStopMic() << endl;
591 cout << CallReleaseMic() << endl;
592 return "EndLooptest";
593 }
594
InitCachebuffer()595 void InitCachebuffer()
596 {
597 g_byteBuffer = make_unique<uint8_t []>(CACHE_BUFFER_SIZE);
598 g_cacheBuffer.buffer = g_byteBuffer.get();
599 g_cacheBuffer.bufLength = CACHE_BUFFER_SIZE;
600 g_cacheBuffer.dataLength = CACHE_BUFFER_SIZE;
601 }
602
InteractiveRun()603 void InteractiveRun()
604 {
605 InitCachebuffer();
606 cout << "Interactive run oh test enter." << endl;
607 bool isInteractiveRun = true;
608 while (isInteractiveRun) {
609 PrintInteractiveUsage();
610 int32_t res = GetUserInput();
611 if (g_interactiveOptStrMap.count(res)) {
612 g_optCode = static_cast<OperationCode>(res);
613 }
614 switch (g_optCode) {
615 case EXIT_INTERACTIVE_TEST:
616 isInteractiveRun = false;
617 break;
618 case START_LOOP_TEST:
619 cout << StartLoopTest() << endl;
620 break;
621 case END_LOOP_TEST:
622 cout << EndLoopTest() << endl;
623 break;
624 case INIT_LOCAL_MIC_OH:
625 cout << ConfigMicTest(false) << endl;
626 break;
627 case INIT_REMOTE_MIC_OH:
628 cout << ConfigMicTest(true) << endl;
629 break;
630 default:
631 auto it = g_interactiveOptFuncMap.find(g_optCode);
632 if (it != g_interactiveOptFuncMap.end() && it->second != nullptr) {
633 CallTestOperationFunc &func = it->second;
634 cout << (*func)() << endl;
635 break;
636 }
637 cout << "Invalid input :" << g_optCode << endl;
638 break;
639 }
640 }
641 cout << "Interactive run oh test end." << endl;
642 }
643
644 } // namespace AudioStandard
645 } // namespace OHOS
646
647 using namespace OHOS::AudioStandard;
main()648 int main()
649 {
650 cout << "Please input 1 or 0 (1 means low latency, 0 means ordinary): " << endl;
651 cin >> g_latencyMode;
652
653 bool isNdkTestRun = true;
654 g_audioNdkTest = make_shared<AudioNdkTest>();
655
656 while (isNdkTestRun) {
657 PrintNdkTestUsage();
658 AudioOHTestType ohTestType = INVALID_OH_TEST;
659 int32_t res = GetUserInput();
660 if (g_audioNdkTestType.count(res)) {
661 ohTestType = static_cast<AudioOHTestType>(res);
662 }
663 switch (ohTestType) {
664 case INTERACTIVE_RUN_MIC_TEST:
665 cout << "OH run mic test, ohTestType: " << ohTestType << endl;
666 InteractiveRun();
667 break;
668 case INTERACTIVE_RUN_LOOP:
669 cout << "OH run loop test, ohTestType: " << ohTestType << endl;
670 InteractiveRun();
671 break;
672 case EXIT_OH_TEST:
673 isNdkTestRun = false;
674 cout << "exit OH test, ohTestType: " << ohTestType << endl;
675 break;
676 default:
677 cout << "invalid input, ohTestType: " << ohTestType << endl;
678 break;
679 }
680 }
681 cout << "Test end!" << endl;
682 return 0;
683 }
684