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 <cinttypes>
17 #include <condition_variable>
18 #include <cstdint>
19 #include <ctime>
20 #include <ostream>
21 #include <sstream>
22 #include <iostream>
23 #include <thread>
24 #include <mutex>
25 #include <map>
26 #include <securec.h>
27 
28 #include <sys/time.h>
29 
30 #include "audio_service_log.h"
31 #include "audio_errors.h"
32 #include "audio_utils.h"
33 #include "audio_process_in_client.h"
34 #include "audio_system_manager.h"
35 #include "parameter.h"
36 #include "pcm2wav.h"
37 
38 using namespace std;
39 namespace OHOS {
40 namespace AudioStandard {
41 namespace {
42     static constexpr long WAV_HEADER_SIZE = 42;
43     static constexpr int64_t SECOND_TO_NANOSECOND = 1000000000;
44     static constexpr int64_t MIC_SLEEP_TIME_US = 2000000000;
45     constexpr int32_t SAMPLE_FORMAT_U8 = 8;
46     constexpr int32_t SAMPLE_FORMAT_S16LE = 16;
47     constexpr int32_t SAMPLE_FORMAT_S24LE = 24;
48     constexpr int32_t SAMPLE_FORMAT_S32LE = 32;
49     enum OperationCode : int32_t {
50         INVALID_OPERATION = -1,
51         INIT_LOCAL_SPK_PROCESS = 0,
52         INIT_REMOTE_SPK_PROCESS = 1,
53         START_SPK_PROCESS = 2,
54         PAUSE_SPK_PROCESS = 3,
55         RESUME_SPK_PROCESS = 4,
56         STOP_SPK_PROCESS = 5,
57         CHANGE_SPK_PROCESS_VOL = 6,
58         RELEASE_SPK_PROCESS = 7,
59 
60         START_LOOP_TEST = 10,
61         END_LOOP_TEST = 11,
62 
63         START_SIGNAL_TEST = 12,
64         END_SIGNAL_TEST = 13,
65 
66         INIT_LOCAL_MIC_PROCESS = 20,
67         INIT_REMOTE_MIC_PROCESS = 21,
68         START_MIC_PROCESS = 22,
69         PAUSE_MIC_PROCESS = 23,
70         RESUME_MIC_PROCESS = 24,
71         STOP_MIC_PROCESS = 25,
72         CHANGE_MIC_PROCESS_VOL = 26,
73         RELEASE_MIC_PROCESS = 27,
74 
75         LOCAL_LATENCY_TEST = 30,
76         REMOTE_LATENCY_TEST = 31,
77 
78         EXIT_INTERACTIVE_TEST = 40,
79     };
80 
81     enum AudioProcessTestType : int32_t {
82         INVALID_PROC_TEST = 0,
83         INTERACTIVE_RUN_SPK_TEST = 1,
84         AUTO_RUN_SPK_TEST = 2,
85         INTERACTIVE_RUN_MIC_TEST = 3,
86         AUTO_RUN_MIC_TEST = 4,
87         INTERACTIVE_RUN_LOOP = 5,
88         RENDER_SIGNAL_TEST = 6,
89         EXIT_PROC_TEST = 7,
90     };
91     enum TestMode : int32_t {
92         RENDER_FILE = 0,
93         RENDER_MIC_LOOP_DATA = 1,
94         RENDER_SIGNAL_DATA = 2,
95     };
96     static constexpr size_t CACHE_BUFFER_SIZE = 960;
97     TestMode g_testMode = RENDER_FILE;
98     bool g_renderSignal = false;
99     int64_t g_stampTime = 0;
100 }
101 
102 class AudioProcessTest;
103 shared_ptr<AudioProcessTest> g_audioProcessTest = nullptr;
104 std::string g_spkfilePath = "";
105 const std::string MIC_FILE_PATH = "/data/data/mic.pcm";
106 FILE *g_spkWavFile = nullptr;
107 FILE *g_micPcmFile = nullptr;
108 std::vector<int64_t> g_playBeepTime_;
109 std::vector<int64_t> g_captureBeepTime_;
110 bool g_isLatencyTesting = false;
111 int32_t g_setVol = 60000;
112 int32_t g_usPerMs = 1000;
113 mutex g_autoRunMutex;
114 condition_variable g_autoRunCV;
115 
116 unique_ptr<uint8_t[]> g_byteBuffer = nullptr;
117 BufferDesc g_cacheBuffer = {nullptr, 0, 0};
118 
119 string ConfigSpkTest(bool isRemote);
120 string CallStartSpk();
121 string CallPauseSpk();
122 string CallResumeSpk();
123 string CallStopSpk();
124 string SetSpkVolume();
125 string CallReleaseSpk();
126 
127 string StartSignalTest();
128 string EndSignalTest();
129 
130 string ConfigMicTest(bool isRemote);
131 string CallStartMic();
132 string CallPauseMic();
133 string CallResumeMic();
134 string CallStopMic();
135 string SetMicVolume();
136 string CallReleaseMic();
137 
138 void CountLatencyTime();
139 string LoopLatencyTest(bool isRemote);
140 string LocalLoopLatencyTest();
141 string RemoteLoopLatencyTest();
142 using CallTestOperationFunc = string (*)();
143 
144 std::map<int32_t, std::string> g_audioProcessTestType = {
145     {INTERACTIVE_RUN_SPK_TEST, "Interactive run spk process test"},
146     {AUTO_RUN_SPK_TEST, "Auto run spk process test"},
147     {INTERACTIVE_RUN_MIC_TEST, "Interactive run mic process test"},
148     {AUTO_RUN_MIC_TEST, "Auto run mic process test"},
149     {INTERACTIVE_RUN_LOOP, "Roundtrip latency test"},
150     {RENDER_SIGNAL_TEST, "Render signal latency test"},
151     {EXIT_PROC_TEST, "Exit audio process test"},
152 };
153 
154 std::map<int32_t, std::string> g_interactiveOptStrMap = {
155     {INIT_LOCAL_SPK_PROCESS, "call local spk init process"},
156     {INIT_REMOTE_SPK_PROCESS, "call remote spk init process"},
157     {START_SPK_PROCESS, "call start spk process"},
158     {PAUSE_SPK_PROCESS, "call pause spk process"},
159     {RESUME_SPK_PROCESS, "call resume spk process"},
160     {STOP_SPK_PROCESS, "call stop spk process"},
161     {CHANGE_SPK_PROCESS_VOL, "change spk process volume"},
162     {RELEASE_SPK_PROCESS, "release spk process"},
163 
164     {START_LOOP_TEST, "start loop"},
165     {END_LOOP_TEST, "end loop"},
166 
167     {START_SIGNAL_TEST, "start signal test"},
168     {END_SIGNAL_TEST, "end signal test"},
169 
170     {INIT_LOCAL_MIC_PROCESS, "call local mic init process"},
171     {INIT_REMOTE_MIC_PROCESS, "call remote mic init process"},
172     {START_MIC_PROCESS, "call start mic process"},
173     {PAUSE_MIC_PROCESS, "call pause mic process"},
174     {RESUME_MIC_PROCESS, "call resume mic process"},
175     {STOP_MIC_PROCESS, "call stop mic process"},
176     {CHANGE_MIC_PROCESS_VOL, "change mic process volume"},
177     {RELEASE_MIC_PROCESS, "release mic process"},
178 
179     {LOCAL_LATENCY_TEST, "call local loop latency test"},
180     {REMOTE_LATENCY_TEST, "call remote loop latency test"},
181 
182     {EXIT_INTERACTIVE_TEST, "exit interactive run test"},
183 };
184 
185 std::map<int32_t, CallTestOperationFunc> g_interactiveOptFuncMap = {
186     {START_SPK_PROCESS, CallStartSpk},
187     {PAUSE_SPK_PROCESS, CallPauseSpk},
188     {RESUME_SPK_PROCESS, CallResumeSpk},
189     {STOP_SPK_PROCESS, CallStopSpk},
190     {CHANGE_SPK_PROCESS_VOL, SetSpkVolume},
191     {RELEASE_SPK_PROCESS, CallReleaseSpk},
192 
193     {START_SIGNAL_TEST, StartSignalTest},
194     {END_SIGNAL_TEST, EndSignalTest},
195 
196     {START_MIC_PROCESS, CallStartMic},
197     {PAUSE_MIC_PROCESS, CallPauseMic},
198     {RESUME_MIC_PROCESS, CallResumeMic},
199     {STOP_MIC_PROCESS, CallStopMic},
200     {CHANGE_MIC_PROCESS_VOL, SetMicVolume},
201     {RELEASE_MIC_PROCESS, CallReleaseMic},
202 
203     {LOCAL_LATENCY_TEST, LocalLoopLatencyTest},
204     {REMOTE_LATENCY_TEST, RemoteLoopLatencyTest},
205 };
206 
207 class AudioProcessTestCallback : public AudioDataCallback {
208 public:
AudioProcessTestCallback(const std::shared_ptr<AudioProcessInClient> & procClient,int32_t spkLoopCnt,AudioMode clientMode)209     AudioProcessTestCallback(const std::shared_ptr<AudioProcessInClient> &procClient,
210         int32_t spkLoopCnt, AudioMode clientMode)
211         : procClient_(procClient), loopCount_(spkLoopCnt), clientMode_(clientMode) {};
212     ~AudioProcessTestCallback() = default;
213 
214     void OnHandleData(size_t length) override;
InitSignalBuffer(const BufferDesc & signalSoundBuffer)215     void InitSignalBuffer(const BufferDesc &signalSoundBuffer)
216     {
217         int ret = memset_s(signalSoundBuffer.buffer, signalSoundBuffer.bufLength, 0, signalSoundBuffer.bufLength);
218         if (ret != EOK) {
219             return;
220         }
221         const int channels = 2; // 2 channels
222         const int samplePerChannel = 96 / channels; // 96 for 1ms
223         int16_t *signalData = static_cast<int16_t *>(static_cast<void *>(signalSoundBuffer.buffer));
224         int16_t bound = 10;
225         for (int idx = 0; idx < samplePerChannel; idx++) {
226             signalData[channels * idx] = bound + static_cast<int16_t>(sinf(2.0f * static_cast<float>(M_PI) * idx /
227                 samplePerChannel) * (SHRT_MAX - bound));
228             for (int c = 1; c < channels; c++) {
229                 signalData[channels * idx + c] = signalData[channels * idx];
230             }
231         }
232     };
233 
234 private:
235     int32_t CaptureToFile(const BufferDesc &bufDesc);
236     int32_t RenderFromFile(const BufferDesc &bufDesc);
237     bool IsFrameHigh(const int16_t *audioData, const int32_t size, int32_t threshold);
238     int64_t RecordBeepTime(const uint8_t *base, const int32_t &sizePerFrame, bool &status);
239     int64_t GetNowTimeUs();
240 
HandleWriteLoopData(const BufferDesc & bufDesc)241     void HandleWriteLoopData(const BufferDesc &bufDesc)
242     {
243         loopCount_++;
244         int32_t periodCount = loopCount_ % 400; // 400 * 0.005 = 2s
245 
246         if (periodCount == 0) {
247             InitSignalBuffer(bufDesc); // set signal data
248             int64_t temp = ClockTime::GetCurNano() - g_stampTime;
249             std::cout << "client read-write latency:" << (temp / AUDIO_MS_PER_SECOND) << " us" << std::endl;
250             return;
251         }
252 
253         int32_t keepQuiteHold = 50;
254         if (periodCount > keepQuiteHold) {
255             return;
256         }
257 
258         // copy mic data in the cache buffer
259         int ret = memcpy_s(static_cast<void *>(bufDesc.buffer), bufDesc.bufLength,
260             static_cast<void *>(g_cacheBuffer.buffer), g_cacheBuffer.bufLength);
261         if (ret != EOK) {
262             AUDIO_WARNING_LOG("memcpy_s failed.");
263         }
264     };
265 
GetCurTime()266     void GetCurTime()
267     {
268         struct timeval tv;
269         struct timezone tz;
270         struct tm *t;
271 
272         gettimeofday(&tv, &tz);
273         t = localtime(&tv.tv_sec);
274         AUDIO_INFO_LOG("ClockTime::GetCurNano is %{public}" PRId64" Low-latency write first data start at"
275             ":%{public}04d-%{public}02d-%{public}02d %{public}02d:%{public}02d:%{public}02d.%{public}03" PRId64" ",
276             ClockTime::GetCurNano(), 1900 + t->tm_year, 1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
277             static_cast<int64_t>(tv.tv_usec / AUDIO_MS_PER_SECOND));
278     }
279 
HandleWriteSignalData(const BufferDesc & bufDesc)280     void HandleWriteSignalData(const BufferDesc &bufDesc)
281     {
282         if (g_renderSignal) {
283             InitSignalBuffer(bufDesc);
284             GetCurTime();
285             g_renderSignal = false;
286         }
287     }
288 
289 private:
290     std::shared_ptr<AudioProcessInClient> procClient_ = nullptr;
291     int32_t loopCount_ = -1; // for loop
292     AudioMode clientMode_ = AUDIO_MODE_PLAYBACK;
293     bool renderFinish_ = false;
294     int32_t playIndex_ = 0;
295     int32_t recordIndex_ = 0;
296     bool isFirstRender = true;
297     bool isFirstCapture = true;
298     int32_t biHighFrameTimeMs = 900000;
299     int64_t playLastTime_ = 0;
300     int64_t recordLastTime_ = 0;
301 };
302 
303 class AudioProcessTest {
304 public:
305     AudioProcessTest() = default;
306     ~AudioProcessTest() = default;
307 
308     int32_t InitSpk(int32_t loopCount, bool isRemote);
309     bool IsInited();
310     bool StartSpk();
311     bool PauseSpk();
312     bool ResumeSpk();
313     bool SetSpkVolume(int32_t vol);
314     bool StopSpk();
315     bool ReleaseSpk();
316 
317     int32_t InitMic(bool isRemote);
318     bool StartMic();
319     bool PauseMic();
320     bool ResumeMic();
321     bool SetMicVolume(int32_t vol);
322     bool StopMic();
323     bool ReleaseMic();
324 
325     int32_t SelectDevice(DeviceRole deviceRole);
326 private:
327     std::shared_ptr<AudioProcessInClient> spkProcessClient_ = nullptr;
328     std::shared_ptr<AudioProcessInClient> micProcessClient_ = nullptr;
329     std::shared_ptr<AudioProcessTestCallback> spkProcClientCb_ = nullptr;
330     std::shared_ptr<AudioProcessTestCallback> micProcClientCb_ = nullptr;
331     int32_t loopCount_ = -1; // for loop
332     bool isInited_ = false;
333 };
334 
GetNowTimeUs()335 int64_t AudioProcessTestCallback::GetNowTimeUs()
336 {
337     std::chrono::microseconds nowUs =
338         std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
339     return nowUs.count();
340 }
341 
IsFrameHigh(const int16_t * audioData,const int32_t size,int32_t threshold)342 bool AudioProcessTestCallback::IsFrameHigh(const int16_t *audioData, const int32_t size, int32_t threshold)
343 {
344     int32_t max = 0;
345     for (int32_t i = 0; i < size; i++) {
346         int16_t f = abs(audioData[i]);
347         if (f > max) {
348             max = f;
349         }
350     }
351     return (max >= threshold) ? true : false;
352 }
353 
RecordBeepTime(const uint8_t * base,const int32_t & sizePerFrame,bool & status)354 int64_t AudioProcessTestCallback::RecordBeepTime(const uint8_t *base, const int32_t &sizePerFrame, bool &status)
355 {
356     int32_t threadhold = 8000;
357     if (IsFrameHigh(reinterpret_cast<const int16_t *>(base),
358         sizePerFrame / sizeof(int16_t), threadhold) == true &&
359         status == true) {
360         status = false;
361         return GetNowTimeUs();
362     } else if (IsFrameHigh(reinterpret_cast<const int16_t *>(base),
363         sizePerFrame / sizeof(int16_t), threadhold) == false) {
364         status = true;
365     }
366     return 0;
367 }
368 
CaptureToFile(const BufferDesc & bufDesc)369 int32_t AudioProcessTestCallback::CaptureToFile(const BufferDesc &bufDesc)
370 {
371     CHECK_AND_RETURN_RET_LOG(g_micPcmFile != nullptr, ERR_INVALID_HANDLE,
372         "%{public}s g_micPcmFile is null.", __func__);
373 
374     size_t cnt = fwrite(bufDesc.buffer, 1, bufDesc.bufLength, g_micPcmFile);
375     CHECK_AND_RETURN_RET_LOG(cnt == bufDesc.bufLength, ERR_WRITE_FAILED,
376         "%{public}s fwrite fail, cnt %{public}zu, bufLength %{public}zu.", __func__, cnt, bufDesc.bufLength);
377     if (g_testMode == RENDER_MIC_LOOP_DATA) {
378         int ret = memcpy_s(static_cast<void *>(g_cacheBuffer.buffer), bufDesc.bufLength,
379             static_cast<void *>(bufDesc.buffer), bufDesc.bufLength);
380         if (ret != EOK) {
381             AUDIO_WARNING_LOG("memcpy_s failed.");
382         }
383         g_stampTime = ClockTime::GetCurNano();
384     }
385     if (g_isLatencyTesting) {
386         if (recordIndex_ == 0) {
387             cout << "First record time : " << GetNowTimeUs() << endl;
388         }
389 
390         int64_t bt = RecordBeepTime(bufDesc.buffer, bufDesc.bufLength, isFirstCapture);
391         if (bt != 0 && g_captureBeepTime_.size() < g_playBeepTime_.size()) {
392             if (GetNowTimeUs() - recordLastTime_ <= biHighFrameTimeMs) {
393                 cout << "catch high frame, but not in 900ms" << endl;
394                 recordIndex_++;
395                 return SUCCESS;
396             }
397             g_captureBeepTime_.push_back(bt);
398             recordLastTime_ = GetNowTimeUs();
399             cout << "Capture beep frame: " << recordIndex_ << " record time : " << GetNowTimeUs() << endl;
400         }
401     }
402     recordIndex_++;
403     return SUCCESS;
404 }
405 
RenderFromFile(const BufferDesc & bufDesc)406 int32_t AudioProcessTestCallback::RenderFromFile(const BufferDesc &bufDesc)
407 {
408     CHECK_AND_RETURN_RET_LOG(g_spkWavFile != nullptr, ERR_INVALID_HANDLE,
409         "%{public}s g_spkWavFile is null.", __func__);
410 
411     if (feof(g_spkWavFile)) {
412         loopCount_--;
413         if (loopCount_ < 0) {
414             fseek(g_spkWavFile, WAV_HEADER_SIZE, SEEK_SET); // infinite loop
415         } else if (loopCount_ == 0) {
416             renderFinish_ = true;
417             g_autoRunCV.notify_all();
418         } else {
419             fseek(g_spkWavFile, WAV_HEADER_SIZE, SEEK_SET);
420         }
421     }
422     if (renderFinish_) {
423         AUDIO_INFO_LOG("%{public}s render finish.", __func__);
424         return SUCCESS;
425     }
426     fread(bufDesc.buffer, 1, bufDesc.bufLength, g_spkWavFile);
427     if (g_isLatencyTesting) {
428         if (playIndex_ == 0) {
429             cout << "First play time: " << GetNowTimeUs() << endl;
430         }
431         int64_t bt = RecordBeepTime(bufDesc.buffer, bufDesc.bufLength, isFirstRender);
432         if (bt != 0) {
433             if (GetNowTimeUs() - playLastTime_ <= biHighFrameTimeMs) {
434                 cout << "Catch high frame, but not in 900ms" << endl;
435                 playIndex_++;
436                 return SUCCESS;
437             }
438             g_playBeepTime_.push_back(bt);
439             playLastTime_ = GetNowTimeUs();
440             cout << "Play beep frame: " << playIndex_ << "play time: " << GetNowTimeUs() << endl;
441         }
442     }
443     playIndex_++;
444     return SUCCESS;
445 }
446 
OnHandleData(size_t length)447 void AudioProcessTestCallback::OnHandleData(size_t length)
448 {
449     Trace callBack("client_n");
450     CHECK_AND_RETURN_LOG(procClient_ != nullptr, "%{public}s procClient is null.", __func__);
451 
452     BufferDesc bufDesc = {nullptr, 0, 0};
453     int32_t ret = procClient_->GetBufferDesc(bufDesc);
454     if (ret != SUCCESS || bufDesc.buffer == nullptr || bufDesc.bufLength ==0) {
455         cout << "GetBufferDesc failed." << endl;
456         return;
457     }
458 
459     if (clientMode_ == AUDIO_MODE_RECORD) {
460         ret = CaptureToFile(bufDesc);
461         CHECK_AND_RETURN_LOG(ret == SUCCESS, "%{public}s capture to file fail, ret %{public}d.",
462             __func__, ret);
463     } else {
464         if (g_testMode == TestMode::RENDER_FILE) {
465             ret = RenderFromFile(bufDesc);
466             CHECK_AND_RETURN_LOG(ret == SUCCESS, "%{public}s render from file fail, ret %{public}d.", __func__, ret);
467         } else if (g_testMode == TestMode::RENDER_MIC_LOOP_DATA) {
468             HandleWriteLoopData(bufDesc);
469         } else if (g_testMode == TestMode::RENDER_SIGNAL_DATA) {
470             HandleWriteSignalData(bufDesc);
471         }
472     }
473     ret = procClient_->Enqueue(bufDesc);
474     CHECK_AND_RETURN_LOG(ret == SUCCESS, "%{public}s enqueue buf fail, clientMode %{public}d, ret %{public}d.",
475         __func__, clientMode_, ret);
476 
477     callBack.End();
478 }
479 
GetSampleFormat(int32_t wavSampleFormat)480 inline AudioSampleFormat GetSampleFormat(int32_t wavSampleFormat)
481 {
482     switch (wavSampleFormat) {
483         case SAMPLE_FORMAT_U8:
484             return AudioSampleFormat::SAMPLE_U8;
485         case SAMPLE_FORMAT_S16LE:
486             return AudioSampleFormat::SAMPLE_S16LE;
487         case SAMPLE_FORMAT_S24LE:
488             return AudioSampleFormat::SAMPLE_S24LE;
489         case SAMPLE_FORMAT_S32LE:
490             return AudioSampleFormat::SAMPLE_S32LE;
491         default:
492             return AudioSampleFormat::INVALID_WIDTH;
493     }
494 }
495 
SelectDevice(DeviceRole deviceRole)496 int32_t AudioProcessTest::SelectDevice(DeviceRole deviceRole)
497 {
498     AudioSystemManager *manager = AudioSystemManager::GetInstance();
499     if (manager == nullptr) {
500         std::cout << "Get AudioSystemManager failed" << std::endl;
501         return ERR_INVALID_OPERATION;
502     }
503 
504     std::vector<sptr<AudioDeviceDescriptor>> devices;
505     if (deviceRole == OUTPUT_DEVICE) {
506         devices = manager->GetDevices(DISTRIBUTED_OUTPUT_DEVICES_FLAG);
507     } else {
508         devices = manager->GetDevices(DISTRIBUTED_INPUT_DEVICES_FLAG);
509     }
510     if (devices.size() != 1) {
511         std::cout << "GetDevices failed, unsupported size:" << devices.size() << std::endl;
512         return ERR_INVALID_OPERATION;
513     }
514 
515     std::cout << "using device:" << devices[0]->networkId_ << std::endl;
516 
517     int32_t ret = 0;
518     if (deviceRole == OUTPUT_DEVICE) {
519         sptr<AudioRendererFilter> filter = new AudioRendererFilter();
520         filter->uid = getuid();
521         filter->rendererInfo.rendererFlags = STREAM_FLAG_FAST;
522         ret = manager->SelectOutputDevice(filter, devices);
523     } else {
524         sptr<AudioCapturerFilter> filter = new AudioCapturerFilter();
525         filter->uid = getuid();
526         filter->capturerInfo.sourceType = SOURCE_TYPE_MIC;
527         filter->capturerInfo.capturerFlags = STREAM_FLAG_FAST;
528         ret = manager->SelectInputDevice(filter, devices);
529     }
530 
531     if (ret == SUCCESS) {
532         std::cout << "SelectDevice seccess" << std::endl;
533     } else {
534         std::cout << "SelectDevice failed, ret:" << ret << std::endl;
535     }
536     return ret;
537 }
538 
InitSpk(int32_t loopCount,bool isRemote)539 int32_t AudioProcessTest::InitSpk(int32_t loopCount, bool isRemote)
540 {
541     if (loopCount < 0) {
542         loopCount_ = 1; // loop once
543     } else if (loopCount == 0) {
544         loopCount_ = -1; // infinite loop
545     } else {
546         loopCount_ = loopCount;
547     }
548     if (isRemote && SelectDevice(OUTPUT_DEVICE) != SUCCESS) {
549         std::cout << "Select remote device error." << std::endl;
550         return ERROR_UNSUPPORTED;
551     }
552 
553     AudioProcessConfig config;
554     config.appInfo.appPid = getpid();
555     config.appInfo.appUid = getuid();
556 
557     config.audioMode = AUDIO_MODE_PLAYBACK;
558 
559     config.rendererInfo.contentType = CONTENT_TYPE_MUSIC;
560     config.rendererInfo.streamUsage = STREAM_USAGE_MEDIA;
561     config.rendererInfo.rendererFlags = STREAM_FLAG_FAST;
562 
563     config.streamInfo.channels = STEREO;
564     config.streamInfo.encoding = ENCODING_PCM;
565     config.streamInfo.format = SAMPLE_S16LE;
566     config.streamInfo.samplingRate = SAMPLE_RATE_48000;
567 
568     config.streamType = STREAM_MUSIC;
569 
570     if (g_testMode == TestMode::RENDER_FILE) {
571         wav_hdr wavHeader;
572         size_t headerSize = sizeof(wav_hdr);
573         size_t bytesRead = fread(&wavHeader, 1, headerSize, g_spkWavFile);
574         if (bytesRead != headerSize) {
575             AUDIO_ERR_LOG("RenderCallbackTest: File header reading error");
576         }
577 
578         config.streamInfo.samplingRate = static_cast<AudioSamplingRate>(wavHeader.SamplesPerSec);
579         config.streamInfo.format = GetSampleFormat(wavHeader.bitsPerSample);
580         config.streamInfo.channels = static_cast<AudioChannel>(wavHeader.NumOfChan);
581 
582         cout << endl << "samplingRate:" << config.streamInfo.samplingRate << endl;
583         cout << "format:" << config.streamInfo.format << endl;
584         cout << "channels:" << config.streamInfo.channels << endl;
585     }
586 
587     spkProcessClient_ = AudioProcessInClient::Create(config);
588     CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, ERR_INVALID_HANDLE,
589         "Client test creat process client fail.");
590 
591     spkProcClientCb_ = std::make_shared<AudioProcessTestCallback>(spkProcessClient_, loopCount_, config.audioMode);
592     int32_t ret = spkProcessClient_->SaveDataCallback(spkProcClientCb_);
593     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Client test save data callback fail, ret %{public}d.", ret);
594     isInited_ = true;
595     return SUCCESS;
596 }
597 
IsInited()598 bool AudioProcessTest::IsInited()
599 {
600     return isInited_;
601 }
602 
StartSpk()603 bool AudioProcessTest::StartSpk()
604 {
605     CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__);
606     int32_t ret = spkProcessClient_->Start();
607     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret);
608     return true;
609 }
610 
PauseSpk()611 bool AudioProcessTest::PauseSpk()
612 {
613     CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__);
614     int32_t ret = spkProcessClient_->Pause();
615     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret);
616     return true;
617 }
618 
ResumeSpk()619 bool AudioProcessTest::ResumeSpk()
620 {
621     CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__);
622     int32_t ret = spkProcessClient_->Resume();
623     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret);
624     return true;
625 }
626 
SetSpkVolume(int32_t vol)627 bool AudioProcessTest::SetSpkVolume(int32_t vol)
628 {
629     CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__);
630     int32_t ret = spkProcessClient_->SetVolume(vol);
631     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret);
632     return true;
633 }
634 
StopSpk()635 bool AudioProcessTest::StopSpk()
636 {
637     CHECK_AND_RETURN_RET_LOG(spkProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__);
638     int32_t ret = spkProcessClient_->Stop();
639     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret);
640     return true;
641 }
642 
ReleaseSpk()643 bool AudioProcessTest::ReleaseSpk()
644 {
645     if (spkProcessClient_ == nullptr) {
646         AUDIO_INFO_LOG("%{public}s process client is already released.", __func__);
647         return true;
648     }
649     int32_t ret = spkProcessClient_->Release();
650     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test release fail, ret %{public}d.", ret);
651     spkProcessClient_ = nullptr;
652     AUDIO_INFO_LOG("client test set nullptr!");
653     return true;
654 }
655 
InitMic(bool isRemote)656 int32_t AudioProcessTest::InitMic(bool isRemote)
657 {
658     AudioProcessConfig config;
659     config.appInfo.appPid = getpid();
660     config.appInfo.appUid = getuid();
661 
662     config.audioMode = AUDIO_MODE_RECORD;
663     config.capturerInfo.sourceType = SOURCE_TYPE_MIC;
664     config.capturerInfo.capturerFlags = STREAM_FLAG_FAST;
665 
666     config.streamInfo.channels = STEREO;
667     config.streamInfo.encoding = ENCODING_PCM;
668     config.streamInfo.format = SAMPLE_S16LE;
669     config.streamInfo.samplingRate = SAMPLE_RATE_48000;
670 
671     if (isRemote && SelectDevice(INPUT_DEVICE) != SUCCESS) {
672         std::cout << "Select remote device error." << std::endl;
673         return ERROR_UNSUPPORTED;
674     }
675 
676     micProcessClient_ = AudioProcessInClient::Create(config);
677     CHECK_AND_RETURN_RET_LOG(micProcessClient_ != nullptr, ERR_INVALID_HANDLE,
678         "Client test creat process client fail.");
679 
680     micProcClientCb_ = std::make_shared<AudioProcessTestCallback>(micProcessClient_, 0, config.audioMode);
681     int32_t ret = micProcessClient_->SaveDataCallback(micProcClientCb_);
682     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Client test save data callback fail, ret %{public}d.", ret);
683     return SUCCESS;
684 }
685 
StartMic()686 bool AudioProcessTest::StartMic()
687 {
688     CHECK_AND_RETURN_RET_LOG(micProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__);
689     int32_t ret = micProcessClient_->Start();
690     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret);
691     return true;
692 }
693 
PauseMic()694 bool AudioProcessTest::PauseMic()
695 {
696     CHECK_AND_RETURN_RET_LOG(micProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__);
697     int32_t ret = micProcessClient_->Pause();
698     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret);
699     return true;
700 }
701 
ResumeMic()702 bool AudioProcessTest::ResumeMic()
703 {
704     CHECK_AND_RETURN_RET_LOG(micProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__);
705     int32_t ret = micProcessClient_->Resume();
706     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret);
707     return true;
708 }
709 
SetMicVolume(int32_t vol)710 bool AudioProcessTest::SetMicVolume(int32_t vol)
711 {
712     CHECK_AND_RETURN_RET_LOG(micProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__);
713     int32_t ret = micProcessClient_->SetVolume(vol);
714     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret);
715     return true;
716 }
717 
StopMic()718 bool AudioProcessTest::StopMic()
719 {
720     CHECK_AND_RETURN_RET_LOG(micProcessClient_ != nullptr, false, "%{public}s process client is null.", __func__);
721     int32_t ret = micProcessClient_->Stop();
722     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test stop fail, ret %{public}d.", ret);
723     return true;
724 }
725 
ReleaseMic()726 bool AudioProcessTest::ReleaseMic()
727 {
728     if (micProcessClient_ == nullptr) {
729         AUDIO_INFO_LOG("%{public}s process client is already released.", __func__);
730         return true;
731     }
732     int32_t ret = micProcessClient_->Release();
733     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false, "Client test release fail, ret %{public}d.", ret);
734     micProcessClient_ = nullptr;
735     AUDIO_INFO_LOG("client test set nullptr!");
736     return true;
737 }
738 
OpenSpkFile()739 bool OpenSpkFile()
740 {
741     if (g_spkWavFile != nullptr) {
742         AUDIO_ERR_LOG("Spk file has been opened, g_spkfilePath %{public}s", g_spkfilePath.c_str());
743         return true;
744     }
745 
746     char path[PATH_MAX] = { 0x00 };
747     if ((strlen(g_spkfilePath.c_str()) > PATH_MAX) || (realpath(g_spkfilePath.c_str(), path) == nullptr)) {
748         return false;
749     }
750     AUDIO_INFO_LOG("spk path = %{public}s", path);
751     g_spkWavFile = fopen(path, "rb");
752     if (g_spkWavFile == nullptr) {
753         AUDIO_ERR_LOG("Unable to open wave file");
754         return false;
755     }
756     return true;
757 }
758 
CloseSpkFile()759 void CloseSpkFile()
760 {
761     if (g_spkWavFile != nullptr) {
762         fclose(g_spkWavFile);
763         g_spkWavFile = nullptr;
764     }
765 }
766 
OpenMicFile()767 bool OpenMicFile()
768 {
769     if (g_micPcmFile != nullptr) {
770         AUDIO_ERR_LOG("Mic file has been opened, MIC_FILE_PATH %{public}s", MIC_FILE_PATH.c_str());
771         return true;
772     }
773 
774     AUDIO_INFO_LOG("mic path = %{public}s", MIC_FILE_PATH.c_str());
775     g_micPcmFile = fopen(MIC_FILE_PATH.c_str(), "ab+");
776     if (g_micPcmFile == nullptr) {
777         AUDIO_ERR_LOG("Unable to open wave file");
778         return false;
779     }
780     return true;
781 }
782 
CloseMicFile()783 void CloseMicFile()
784 {
785     if (g_micPcmFile != nullptr) {
786         fclose(g_micPcmFile);
787         g_micPcmFile = nullptr;
788     }
789 }
790 
GetArgs(const std::string & args)791 inline int32_t GetArgs(const std::string &args)
792 {
793     int32_t value = 0;
794     stringstream valueStr;
795     valueStr << args;
796     valueStr >> value;
797     return value;
798 }
799 
PrintInteractiveUsage()800 void PrintInteractiveUsage()
801 {
802     cout << endl << "======================= InteractiveRunTestSelect ============================" << endl;
803     cout << "You can respond to instructions for corresponding option:" << endl;
804     for (auto it = g_interactiveOptStrMap.begin(); it != g_interactiveOptStrMap.end(); it ++) {
805         cout << "\t enter " << it->first << " : " << it->second << endl;
806     }
807 }
808 
PrintProcTestUsage()809 void PrintProcTestUsage()
810 {
811     cout << endl << "========================== ProcessTestSelect ================================" << endl;
812     cout << "You can respond to instructions for corresponding test:" << endl;
813     for (auto it = g_audioProcessTestType.begin(); it != g_audioProcessTestType.end(); it ++) {
814         cout << it->first << ". " << it->second << endl;
815     }
816 }
817 
PrintUsage()818 void PrintUsage()
819 {
820     cout << "[Audio Process Client Test App]" << endl << endl;
821     cout << "Supported Functionalities:" << endl;
822     cout << "  a) Auto run local spk test." << endl;
823     cout << "  b) Interactive run local/remote spk test." << endl;
824     cout << "  c) Auto run remote mic test." << endl;
825     cout << "  d) Interactive run remote mic test." << endl;
826     cout << "================================Usage=======================================" << endl << endl;
827 
828     cout << "-a\n\tAuto run local spk process test, pelese input the following after select." << endl;
829     cout << "\tUsage : <wav-file-path> <play-loop-count>" << endl;
830     cout << "\t       if <play-loop-count> equals to 0, it will loop infinitely." << endl;
831     cout << "\tExample 1 : /data/data/48kHz_16bit.wav 0" << endl;
832     cout << "\tExample 2 : /data/data/48kHz_16bit.wav 2" << endl << endl;
833 
834     cout << "-b\n\tInteractive run local/remote spk test, pelese input the following after select." << endl;
835     cout << "\tUsage : <wav-file-path>" << endl;
836 
837     cout << "-c\n\tAuto run remote mic process test, pelese input the following after select." << endl;
838     cout << "\tUsage : <record-time-in-seconds>" << endl;
839     cout << "\tGenerate the specified time span record file, path : /data/data/mic.pcm" << endl;
840 
841     cout << "-d\n\tInteractive run remote mic test." << endl;
842     cout << "\tGenerate record file from start to stop, path : /data/data/mic.pcm" << endl;
843 }
844 
GetUserInput()845 int32_t GetUserInput()
846 {
847     int32_t res = -1; // result
848     size_t count = 3; // try three time
849     cout << ">>";
850     cin >> res;
851     while (cin.fail() && count-- > 0) {
852         cin.clear();
853         cin.ignore();
854         cout << "invalid input, not a number! Please retry with a number." << endl;
855         cout << ">>";
856         cin >> res;
857     }
858     return res;
859 }
860 
AutoRunSpk()861 void AutoRunSpk()
862 {
863     cout << "Auto run spk process test enter, please input loopCount and path:" << endl;
864     int32_t loopCount = GetUserInput();
865     std::string palyFilePath;
866     cin >> palyFilePath;
867     g_spkfilePath = palyFilePath;
868 
869     if (!OpenSpkFile()) {
870         cout << "open spk file path failed!" << g_spkfilePath << endl;
871         return;
872     }
873     if (g_audioProcessTest->InitSpk(loopCount, false) != SUCCESS) {
874         cout << "Spk init failed!" << endl;
875         return;
876     }
877 
878     do {
879         if (!g_audioProcessTest->StartSpk()) {
880             cout << "Spk start failed!" << endl;
881             break;
882         }
883         int volShift = 15; // helf of 1 << 16
884         if (!g_audioProcessTest->SetSpkVolume(1 << volShift)) {
885             cout << "Spk set volume " << volShift << " failed!" << endl;
886             break;
887         }
888 
889         unique_lock<mutex> lock(g_autoRunMutex);
890         g_autoRunCV.wait(lock);
891         cout << "AutoRunSpk end" << endl;
892 
893         if (!g_audioProcessTest->StopSpk()) {
894             cout << "Spk stop failed!" << endl;
895             break;
896         }
897     } while (false);
898 
899     if (!g_audioProcessTest->ReleaseSpk()) {
900         cout << "Spk release failed!" << endl;
901     }
902     CloseSpkFile();
903 }
904 
AutoRunMic()905 void AutoRunMic()
906 {
907     cout << "Auto run mic process test enter, please input recordTimeS:" << endl;
908     int32_t recordTimeS = GetUserInput();
909     if (!OpenMicFile()) {
910         cout << "open mic file path failed!" << g_spkfilePath << endl;
911         return;
912     }
913 
914     if (g_audioProcessTest->InitMic(false) != SUCCESS) {
915         cout << "Mic init failed!" << endl;
916         return;
917     }
918 
919     do {
920         if (!g_audioProcessTest->StartMic()) {
921             cout << "Mic start failed!" << endl;
922             break;
923         }
924         int volShift = 15; // helf of 1 << 16
925         if (!g_audioProcessTest->SetMicVolume(1 << volShift)) {
926             cout << "Mic set volume " << volShift << " failed!" << endl;
927             break;
928         }
929 
930         cout << "wait " << recordTimeS << "s for capture frame..." << endl;
931         ClockTime::RelativeSleep(recordTimeS * SECOND_TO_NANOSECOND);
932         cout << "AutoRunMic end" << endl;
933 
934         if (!g_audioProcessTest->StopMic()) {
935             cout << "Mic stop failed!" << endl;
936             break;
937         }
938     } while (false);
939 
940     if (!g_audioProcessTest->ReleaseMic()) {
941         cout << "Mic release failed!" << endl;
942     }
943     CloseMicFile();
944 }
945 
ConfigSpkTest(bool isRemote)946 string ConfigSpkTest(bool isRemote)
947 {
948     cout << "Please input spk file path:" << endl;
949     std::string palyFilePath;
950     cin >> palyFilePath;
951     g_spkfilePath = palyFilePath;
952 
953     if (!OpenSpkFile()) {
954         cout << "Open spk file path failed!" << g_spkfilePath << endl;
955         return "Open spk wav file fail";
956     }
957     int32_t ret = g_audioProcessTest->InitSpk(0, isRemote);
958     if (ret != SUCCESS) {
959         return "Spk init failed";
960     }
961     return "Spk init SUCCESS";
962 }
963 
LocalLoopLatencyTest()964 string LocalLoopLatencyTest()
965 {
966     return LoopLatencyTest(false);
967 }
968 
RemoteLoopLatencyTest()969 string RemoteLoopLatencyTest()
970 {
971     return LoopLatencyTest(true);
972 }
973 
CountLatencyTime()974 void CountLatencyTime()
975 {
976     int32_t playSize = g_playBeepTime_.size();
977     if (g_playBeepTime_.size() != g_captureBeepTime_.size()) {
978         cout << "Record num is not equal (" << playSize << "  " << g_captureBeepTime_.size() << ")" << endl;
979         return;
980     }
981     cout << "record " << playSize << "times frame high." << endl;
982     int32_t sum = 0;
983     for (int32_t i = 0; i < playSize; i++) {
984         cout << "Send: " << g_playBeepTime_[i] << " Received: " <<
985             g_captureBeepTime_[i] << endl;
986         cout << "Time is: " << ((g_captureBeepTime_[i] - g_playBeepTime_[i]) / g_usPerMs) << endl;
987         sum += g_captureBeepTime_[i] - g_playBeepTime_[i];
988     }
989     if (playSize == 0) {
990         cout << "playSize is 0;" << endl;
991         return;
992     }
993     cout << "Remote audio latency in average is: " << sum / playSize << " (us)." << endl;
994 
995     g_playBeepTime_.clear();
996     g_captureBeepTime_.clear();
997     g_isLatencyTesting = false;
998 }
999 
LoopLatencyTest(bool isRemote)1000 string LoopLatencyTest(bool isRemote)
1001 {
1002     cout << "=== LoopLatencyTest ===";
1003     if (isRemote) {
1004         cout << "**Remote**" << endl;
1005     } else {
1006         cout << "**Local**" << endl;
1007     }
1008     g_isLatencyTesting = true;
1009 
1010     if (!OpenMicFile()) {
1011         return "Open mic file path failed!" + MIC_FILE_PATH;
1012     }
1013     g_audioProcessTest->InitMic(isRemote);
1014     g_audioProcessTest->StartMic();
1015     cout << "MIC start success, begin to record." << endl;
1016 
1017     g_spkfilePath = "/data/bi.wav";
1018     if (!OpenSpkFile()) {
1019         return "Open spk file path failed!" + g_spkfilePath;
1020     }
1021 
1022     int32_t ret = g_audioProcessTest->InitSpk(1, isRemote);
1023     if (ret != SUCCESS) {
1024         return "init spk failed";
1025     }
1026     g_audioProcessTest->StartSpk();
1027     g_audioProcessTest->SetSpkVolume(g_setVol);
1028     cout << "SPK start success. begin to play." << endl;
1029 
1030     cout << "running..." << endl;
1031 
1032     unique_lock<mutex> lock(g_autoRunMutex);
1033     g_autoRunCV.wait(lock);
1034     ClockTime::RelativeSleep(MIC_SLEEP_TIME_US);
1035     //release
1036     g_audioProcessTest->StopMic();
1037     g_audioProcessTest->ReleaseMic();
1038     CloseMicFile();
1039     cout << "MIC stop success." << endl;
1040 
1041     g_audioProcessTest->StopSpk();
1042     g_audioProcessTest->ReleaseSpk();
1043     CloseSpkFile();
1044     cout << "SPK stop success." << endl;
1045 
1046     // cout latency time
1047     CountLatencyTime();
1048     return "Loop latency test success";
1049 }
1050 
CallStartSpk()1051 string CallStartSpk()
1052 {
1053     if (!g_audioProcessTest->StartSpk()) {
1054         return "Spk start failed";
1055     }
1056     return "Spk start SUCCESS";
1057 }
1058 
CallPauseSpk()1059 string CallPauseSpk()
1060 {
1061     if (!g_audioProcessTest->PauseSpk()) {
1062         return "Spk pause failed";
1063     }
1064     return "Spk pause SUCCESS";
1065 }
1066 
CallResumeSpk()1067 string CallResumeSpk()
1068 {
1069     if (!g_audioProcessTest->ResumeSpk()) {
1070         return "Spk resume failed";
1071     }
1072     return "Spk resume SUCCESS";
1073 }
1074 
CallStopSpk()1075 string CallStopSpk()
1076 {
1077     if (!g_audioProcessTest->StopSpk()) {
1078         return "Spk stop failed";
1079     }
1080     return "Spk stop SUCCESS";
1081 }
1082 
SetSpkVolume()1083 string SetSpkVolume()
1084 {
1085     int32_t vol = GetUserInput();
1086     if (!g_audioProcessTest->SetSpkVolume(vol)) {
1087         return "Spk set volume failed";
1088     }
1089     return "Spk set volume SUCCESS";
1090 }
1091 
CallReleaseSpk()1092 string CallReleaseSpk()
1093 {
1094     if (!g_audioProcessTest->ReleaseSpk()) {
1095         return "Spk release failed";
1096     }
1097     CloseSpkFile();
1098     return "Spk release SUCCESS";
1099 }
1100 
ConfigMicTest(bool isRemote)1101 string ConfigMicTest(bool isRemote)
1102 {
1103     if (!OpenMicFile()) {
1104         cout << "Open mic file path failed!" << g_spkfilePath << endl;
1105         return "Open mic pcm file fail";
1106     }
1107 
1108     int32_t ret = g_audioProcessTest->InitMic(isRemote);
1109     if (ret != SUCCESS) {
1110         return "Mic init failed";
1111     }
1112     return "Mic init SUCCESS";
1113 }
1114 
CallStartMic()1115 string CallStartMic()
1116 {
1117     if (!g_audioProcessTest->StartMic()) {
1118         return "Mic start failed";
1119     }
1120     return "Mic start SUCCESS";
1121 }
1122 
CallPauseMic()1123 string CallPauseMic()
1124 {
1125     if (!g_audioProcessTest->PauseMic()) {
1126         return "Mic pause failed";
1127     }
1128     return "Mic pause SUCCESS";
1129 }
1130 
CallResumeMic()1131 string CallResumeMic()
1132 {
1133     if (!g_audioProcessTest->ResumeMic()) {
1134         return "Mic resume failed";
1135     }
1136     return "Mic resume SUCCESS";
1137 }
1138 
CallStopMic()1139 string CallStopMic()
1140 {
1141     if (!g_audioProcessTest->StopMic()) {
1142         return "Mic stop failed";
1143     }
1144     return "Mic stop SUCCESS";
1145 }
1146 
SetMicVolume()1147 string SetMicVolume()
1148 {
1149     int32_t vol = GetUserInput();
1150     if (!g_audioProcessTest->SetMicVolume(vol)) {
1151         return "Mic set volume failed";
1152     }
1153     return "Mic set volume SUCCESS";
1154 }
1155 
CallReleaseMic()1156 string CallReleaseMic()
1157 {
1158     if (!g_audioProcessTest->ReleaseMic()) {
1159         return "Mic release failed";
1160     }
1161     CloseMicFile();
1162     return "Mic release SUCCESS";
1163 }
1164 
StartLoopTest()1165 string StartLoopTest()
1166 {
1167     std::cout << ConfigMicTest(false);
1168     std::cout << CallStartMic();
1169     std::cout << endl;
1170 
1171     int32_t ret = g_audioProcessTest->InitSpk(0, false);
1172     if (ret != SUCCESS) {
1173         CallReleaseMic();
1174         return "init spk failed";
1175     } else {
1176         std::cout << "init spk success" << endl;
1177     }
1178 
1179     std::cout << CallStartSpk();
1180     std::cout << endl;
1181     return "StartLoopTest success!";
1182 }
1183 
EndLoopTest()1184 string EndLoopTest()
1185 {
1186     std::cout << CallReleaseSpk();
1187     std::cout << endl;
1188     std::cout << CallStopMic();
1189     std::cout << endl;
1190     std::cout << CallReleaseMic();
1191     std::cout << endl;
1192     return "EndLooptest";
1193 }
1194 
StartSignalTest()1195 string StartSignalTest()
1196 {
1197     if (g_audioProcessTest == nullptr) {
1198         return "StartSignalTest failed";
1199     }
1200 
1201     if (!g_audioProcessTest->IsInited()) {
1202         if (g_audioProcessTest->InitSpk(0, false) != SUCCESS) {
1203             return "init spk failed";
1204         }
1205         uint32_t tempSleep = 10000; // wait for 10ms
1206         usleep(tempSleep);
1207         CallStartSpk();
1208     }
1209     g_renderSignal = true;
1210     return "call signal";
1211 }
1212 
EndSignalTest()1213 string EndSignalTest()
1214 {
1215     return CallReleaseSpk();
1216 }
1217 
1218 
InitCachebuffer()1219 void InitCachebuffer()
1220 {
1221     g_byteBuffer = std::make_unique<uint8_t []>(CACHE_BUFFER_SIZE);
1222     g_cacheBuffer.buffer = g_byteBuffer.get();
1223     g_cacheBuffer.bufLength = CACHE_BUFFER_SIZE;
1224     g_cacheBuffer.dataLength = CACHE_BUFFER_SIZE;
1225 }
1226 
GetOptCode()1227 OperationCode GetOptCode()
1228 {
1229     int32_t res = GetUserInput();
1230     if (g_interactiveOptStrMap.count(res)) {
1231         return static_cast<OperationCode>(res);
1232     }
1233     return INVALID_OPERATION;
1234 }
1235 
InteractiveRun()1236 void InteractiveRun()
1237 {
1238     if (g_testMode == TestMode::RENDER_MIC_LOOP_DATA) {
1239         InitCachebuffer();
1240     }
1241     cout << "Interactive run process test enter." << endl;
1242     bool isInteractiveRun = true;
1243     while (isInteractiveRun) {
1244         PrintInteractiveUsage();
1245         OperationCode optCode = GetOptCode();
1246         switch (optCode) {
1247             case EXIT_INTERACTIVE_TEST:
1248                 isInteractiveRun = false;
1249                 break;
1250             case INIT_LOCAL_SPK_PROCESS:
1251                 cout << ConfigSpkTest(false) << endl;
1252                 break;
1253             case INIT_REMOTE_SPK_PROCESS:
1254                 cout << ConfigSpkTest(true) << endl;
1255                 break;
1256             case START_LOOP_TEST:
1257                 cout << StartLoopTest() << endl;
1258                 break;
1259             case END_LOOP_TEST:
1260                 cout << EndLoopTest() << endl;
1261                 break;
1262             case INIT_LOCAL_MIC_PROCESS:
1263                 cout << ConfigMicTest(false) << endl;
1264                 break;
1265             case INIT_REMOTE_MIC_PROCESS:
1266                 cout << ConfigMicTest(true) << endl;
1267                 break;
1268             case LOCAL_LATENCY_TEST:
1269                 cout << LocalLoopLatencyTest() << endl;
1270                 break;
1271             case REMOTE_LATENCY_TEST:
1272                 cout << RemoteLoopLatencyTest() << endl;
1273                 break;
1274             default:
1275                 auto it = g_interactiveOptFuncMap.find(optCode);
1276                 if (it != g_interactiveOptFuncMap.end() && it->second != nullptr) {
1277                     CallTestOperationFunc &func = it->second;
1278                     cout << (*func)() << endl;
1279                     break;
1280                 }
1281                 cout << "Invalid input :" << optCode << endl;
1282                 break;
1283         }
1284     }
1285     cout << "Interactive run process test end." << endl;
1286 }
1287 
SetSysPara(const std::string key,int32_t & value)1288 bool SetSysPara(const std::string key, int32_t &value)
1289 {
1290     auto res = SetParameter(key.c_str(), std::to_string(value).c_str());
1291     if (res < 0) {
1292         AUDIO_WARNING_LOG("SetSysPara fail, key:%{public}s res:%{public}d", key.c_str(), res);
1293         return false;
1294     }
1295     AUDIO_INFO_LOG("SetSysPara success.");
1296     return true;
1297 }
1298 } // namespace AudioStandard
1299 } // namespace OHOS
1300 
1301 using namespace OHOS::AudioStandard;
main()1302 int main()
1303 {
1304     AUDIO_INFO_LOG("AudioProcessClientTest test enter.");
1305 
1306     PrintUsage();
1307     g_audioProcessTest = make_shared<AudioProcessTest>();
1308 
1309     bool isProcTestRun = true;
1310     while (isProcTestRun) {
1311         PrintProcTestUsage();
1312         AudioProcessTestType procTestType = INVALID_PROC_TEST;
1313         g_testMode = TestMode::RENDER_FILE;
1314         int32_t res = GetUserInput();
1315         if (g_audioProcessTestType.count(res)) {
1316             procTestType = static_cast<AudioProcessTestType>(res);
1317         }
1318         switch (procTestType) {
1319             case INTERACTIVE_RUN_SPK_TEST:
1320             case INTERACTIVE_RUN_MIC_TEST:
1321                 InteractiveRun();
1322                 break;
1323             case INTERACTIVE_RUN_LOOP:
1324                 g_testMode = TestMode::RENDER_MIC_LOOP_DATA;
1325                 InteractiveRun();
1326                 break;
1327             case RENDER_SIGNAL_TEST:
1328                 g_testMode = TestMode::RENDER_SIGNAL_DATA;
1329                 InteractiveRun();
1330                 break;
1331             case AUTO_RUN_SPK_TEST:
1332                 AutoRunSpk();
1333                 break;
1334             case AUTO_RUN_MIC_TEST:
1335                 AutoRunMic();
1336                 break;
1337             case EXIT_PROC_TEST:
1338                 isProcTestRun = false;
1339                 break;
1340             default:
1341                 cout << "invalid input, procTestType: " << procTestType << endl;
1342                 break;
1343         }
1344     }
1345     AUDIO_INFO_LOG("AudioProcessClientTest test end.");
1346     return 0;
1347 }
1348