• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <cstdio>
16 #include <iostream>
17 #include <unistd.h>
18 
19 #include "audio_capturer.h"
20 #include "audio_errors.h"
21 #include "audio_info.h"
22 #include "audio_service_log.h"
23 #include "audio_renderer.h"
24 #include "audio_system_manager.h"
25 #include "parameter.h"
26 #include "pcm2wav.h"
27 
28 using namespace std;
29 namespace OHOS {
30 namespace AudioStandard {
31 enum AudioOptCode : int32_t {
32     INVALID_OPERATION = -1,
33     INIT_LOCAL_SPK = 0,
34     INIT_REMOTE_SPK = 1,
35     START_SPK = 2,
36     STOP_SPK = 3,
37     SWITCH_SPK = 4,
38     RELEASE_SPK = 5,
39     INIT_LOCAL_MIC = 6,
40     INIT_REMOTE_MIC = 7,
41     START_MIC = 8,
42     STOP_MIC = 9,
43     SWITCH_MIC = 10,
44     RELEASE_MIC = 11,
45     EXIT_DEMO = 12,
46     SATELLITE_ON = 13,
47     SATELLITE_OFF = 14,
48 };
49 
50 std::map<int32_t, std::string> g_OptStrMap = {
51     {INIT_LOCAL_SPK, "call local spk init process"},
52     {INIT_REMOTE_SPK, "call remote spk init process"},
53     {START_SPK, "call start spk process"},
54     {STOP_SPK, "call stop spk process"},
55     {SWITCH_SPK, "call switch spk device process"},
56     {RELEASE_SPK, "release spk process"},
57 
58     {INIT_LOCAL_MIC, "call local mic init process"},
59     {INIT_REMOTE_MIC, "call remote mic init process"},
60     {START_MIC, "call start mic process"},
61     {STOP_MIC, "call stop mic process"},
62     {SWITCH_MIC, "call switch mic device process"},
63     {RELEASE_MIC, "release mic process"},
64     {SATELLITE_ON, "call create audio process when isSatellite is true"},
65     {SATELLITE_OFF, "call create audio process when isSatellite is false"},
66 
67     {EXIT_DEMO, "exit interactive run test"},
68 };
69 
70 constexpr int32_t UID_FOUNDATION_SA = 5523;
71 
72 class PlaybackTest : public AudioRendererWriteCallback,
73     public AudioCapturerReadCallback,
74     public std::enable_shared_from_this<PlaybackTest> {
75 public:
76     int32_t InitRenderer(bool isFast);
77     int32_t StartPlay();
78     int32_t StopPlay();
79     int32_t ReleaseRenderer();
80     int32_t InitCapturer(bool isFast);
81     int32_t StartCapture();
82     int32_t StopCapture();
83     int32_t ReleaseCapture();
84     void OnWriteData(size_t length) override;
85     void OnReadData(size_t length) override;
86     bool OpenSpkFile(const std::string &spkFilePath);
87     bool OpenMicFile(const std::string &micFilePath);
88     void CloseSpkFile();
89     void CloseMicFile();
90     int32_t SwitchDevice(DeviceRole deviceRole);
91     void SetSpkRemote(bool isRemote);
92     bool GetSpkRemote();
93     void SetMicRemote(bool isRemote);
94     bool GetMicRemote();
95     int32_t InitSatelliteProcess(bool satellite);
96 
97 private:
98     int32_t SwitchOutputDevice();
99     int32_t SwitchInputDevice();
100 
101 private:
102     std::unique_ptr<AudioStandard::AudioRenderer> audioRenderer_ = nullptr;
103     std::unique_ptr<AudioStandard::AudioCapturer> audioCapturer_ = nullptr;
104     static constexpr long WAV_HEADER_SIZE = 44;
105     bool needSkipWavHeader_ = true;
106     FILE *spkWavFile_ = nullptr;
107     FILE *micWavFile_ = nullptr;
108     bool isSpkFast_ = false;
109     bool isMicFast_ = false;
110     bool isSpkRemote_ = false;
111     bool isMicRemote_ = false;
112 };
113 
OnWriteData(size_t length)114 void PlaybackTest::OnWriteData(size_t length)
115 {
116     BufferDesc bufDesc;
117     if (audioRenderer_ == nullptr) {
118         AUDIO_ERR_LOG("audioRenderer is nullptr.");
119         return;
120     }
121     audioRenderer_->GetBufferDesc(bufDesc);
122 
123     if (spkWavFile_ == nullptr) {
124         AUDIO_ERR_LOG("spkWavFile_ is nullptr.");
125         return;
126     }
127     if (needSkipWavHeader_) {
128         fseek(spkWavFile_, WAV_HEADER_SIZE, SEEK_SET);
129         needSkipWavHeader_ = false;
130     }
131     if (feof(spkWavFile_)) {
132         fseek(spkWavFile_, WAV_HEADER_SIZE, SEEK_SET); // infinite loop
133     }
134     fread(bufDesc.buffer, 1, bufDesc.bufLength, spkWavFile_);
135     AUDIO_INFO_LOG("%{public}s OnWriteData data length: %{public}zu.", __func__, bufDesc.bufLength);
136     audioRenderer_->Enqueue(bufDesc);
137 }
138 
OpenSpkFile(const std::string & spkFilePath)139 bool PlaybackTest::OpenSpkFile(const std::string &spkFilePath)
140 {
141     if (spkWavFile_ != nullptr) {
142         AUDIO_ERR_LOG("Spk file has been opened, spkFilePath %{public}s", spkFilePath.c_str());
143         return true;
144     }
145 
146     char path[PATH_MAX] = { 0x00 };
147     if ((strlen(spkFilePath.c_str()) > PATH_MAX) || (realpath(spkFilePath.c_str(), path) == nullptr)) {
148         return false;
149     }
150     AUDIO_INFO_LOG("spk path = %{public}s", path);
151     spkWavFile_ = fopen(path, "rb");
152     if (spkWavFile_ == nullptr) {
153         AUDIO_ERR_LOG("Unable to open wave file");
154         return false;
155     }
156     return true;
157 }
158 
CloseSpkFile()159 void PlaybackTest::CloseSpkFile()
160 {
161     if (spkWavFile_ != nullptr) {
162         fclose(spkWavFile_);
163         spkWavFile_ = nullptr;
164     }
165 }
166 
SetSpkRemote(bool isRemote)167 void PlaybackTest::SetSpkRemote(bool isRemote)
168 {
169     isSpkRemote_ = isRemote;
170 }
171 
GetSpkRemote()172 bool PlaybackTest::GetSpkRemote()
173 {
174     return isSpkRemote_;
175 }
176 
SetMicRemote(bool isRemote)177 void PlaybackTest::SetMicRemote(bool isRemote)
178 {
179     isMicRemote_ = isRemote;
180 }
181 
GetMicRemote()182 bool PlaybackTest::GetMicRemote()
183 {
184     return isMicRemote_;
185 }
186 
InitRenderer(bool isFast)187 int32_t PlaybackTest::InitRenderer(bool isFast)
188 {
189     AudioStandard::AudioRendererOptions rendererOptions = {
190         {
191             AudioStandard::AudioSamplingRate::SAMPLE_RATE_48000,
192             AudioStandard::AudioEncodingType::ENCODING_PCM,
193             AudioStandard::AudioSampleFormat::SAMPLE_S16LE,
194             AudioStandard::AudioChannel::STEREO,
195         },
196         {
197             AudioStandard::ContentType::CONTENT_TYPE_UNKNOWN,
198             AudioStandard::StreamUsage::STREAM_USAGE_GAME,
199             isFast ? AudioStandard::STREAM_FLAG_FAST : AudioStandard::STREAM_FLAG_NORMAL, // fast audio stream
200         }
201     };
202     audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions);
203     if (audioRenderer_ == nullptr) {
204         AUDIO_ERR_LOG("Audio renderer create failed.");
205         return -1;
206     }
207     std::string path = "/data/test.wav";
208     OpenSpkFile(path);
209     int32_t ret = audioRenderer_->SetRenderMode(RENDER_MODE_CALLBACK);
210     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Set render mode callback fail, ret %{public}d.", ret);
211     ret = audioRenderer_->SetRendererWriteCallback(shared_from_this());
212     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Client test save data callback fail, ret %{public}d.", ret);
213     AUDIO_INFO_LOG("Audio renderer create success.");
214     isSpkFast_ = isFast;
215     return 0;
216 }
217 
InitSatelliteProcess(bool satellite)218 int32_t PlaybackTest::InitSatelliteProcess(bool satellite)
219 {
220     AudioStandard::AudioRendererOptions rendererOptions = {
221         {
222             AudioStandard::AudioSamplingRate::SAMPLE_RATE_48000,
223             AudioStandard::AudioEncodingType::ENCODING_PCM,
224             AudioStandard::AudioSampleFormat::SAMPLE_S16LE,
225             AudioStandard::AudioChannel::STEREO,
226         },
227         {
228             AudioStandard::ContentType::CONTENT_TYPE_UNKNOWN,
229             AudioStandard::StreamUsage::STREAM_USAGE_GAME,
230         }
231     };
232     rendererOptions.rendererInfo.isSatellite = satellite;
233     rendererOptions.rendererInfo.streamUsage = STREAM_USAGE_VOICE_MODEM_COMMUNICATION;
234     setuid(UID_FOUNDATION_SA);
235     AUDIO_ERR_LOG("Satellite process uid: %{public}d", static_cast<int32_t>(getuid()));
236     audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions);
237     if (audioRenderer_ == nullptr) {
238         AUDIO_ERR_LOG("Satellite process create failed.");
239         return -1;
240     }
241     std::string path = "/data/test.wav";
242     OpenSpkFile(path);
243     int32_t ret = audioRenderer_->SetRenderMode(RENDER_MODE_CALLBACK);
244     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Set render mode callback fail, ret %{public}d.", ret);
245     ret = audioRenderer_->SetRendererWriteCallback(shared_from_this());
246     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Client test save data callback fail, ret %{public}d.", ret);
247     AUDIO_INFO_LOG("Satellite process create success.");
248     return 0;
249 }
250 
SwitchDevice(DeviceRole deviceRole)251 int32_t PlaybackTest::SwitchDevice(DeviceRole deviceRole)
252 {
253     if (deviceRole == OUTPUT_DEVICE) {
254         return SwitchOutputDevice();
255     } else {
256         return SwitchInputDevice();
257     }
258 }
259 
SwitchOutputDevice()260 int32_t PlaybackTest::SwitchOutputDevice()
261 {
262     cout << "Select output device. current play device: " << isSpkRemote_ << "(0 : local, 1 : remote)" << endl;
263     AudioSystemManager *manager = AudioSystemManager::GetInstance();
264     if (manager == nullptr) {
265         cout << "Get AudioSystemManager failed" << std::endl;
266         return ERR_INVALID_OPERATION;
267     }
268 
269     vector<std::shared_ptr<AudioDeviceDescriptor>> devices;
270     if (isSpkRemote_) {
271         devices = manager->GetDevices(OUTPUT_DEVICES_FLAG);
272         vector<std::shared_ptr<AudioDeviceDescriptor>>::iterator it;
273         for (it = devices.begin(); it != devices.end();) {
274             if ((*it)->deviceType_ != DEVICE_TYPE_SPEAKER) {
275                 it = devices.erase(it);
276             } else {
277                 it++;
278             }
279         }
280     } else {
281         devices = manager->GetDevices(DISTRIBUTED_OUTPUT_DEVICES_FLAG);
282     }
283     if (devices.size() != 1) {
284         cout << "GetDevices failed, find no device, unsupported size:" << devices.size() << endl;
285         return ERR_INVALID_OPERATION;
286     }
287 
288     cout << "using device:" << devices[0]->networkId_ << endl;
289 
290     int32_t ret = -1;
291 
292     sptr<AudioRendererFilter> filter = new AudioRendererFilter();
293     filter->uid = getuid();
294     if (isSpkFast_) {
295         filter->rendererInfo.rendererFlags = STREAM_FLAG_FAST;
296     }
297     ret = manager->SelectOutputDevice(filter, devices);
298     if (ret == SUCCESS) {
299         isSpkRemote_ = !isSpkRemote_;
300         cout << "Select output device success. current play device:" <<
301             isSpkRemote_ << "(0 : local, 1 : remote)" << endl;
302     } else {
303         cout << "SelectOutputDevice failed, ret:" << ret << endl;
304     }
305     return ret;
306 }
307 
SwitchInputDevice()308 int32_t PlaybackTest::SwitchInputDevice()
309 {
310     AudioSystemManager *manager = AudioSystemManager::GetInstance();
311     if (manager == nullptr) {
312         cout << "Get AudioSystemManager failed" << std::endl;
313         return ERR_INVALID_OPERATION;
314     }
315 
316     vector<std::shared_ptr<AudioDeviceDescriptor>> devices;
317     if (isMicRemote_) {
318         devices = manager->GetDevices(INPUT_DEVICES_FLAG);
319     } else {
320         devices = manager->GetDevices(DISTRIBUTED_INPUT_DEVICES_FLAG);
321     }
322     if (devices.size() != 1) {
323         cout << "GetDevices failed, find no device, unsupported size:" << devices.size() << endl;
324         return ERR_INVALID_OPERATION;
325     }
326 
327     cout << "using device:" << devices[0]->networkId_ << endl;
328 
329     int32_t ret = -1;
330 
331     sptr<AudioCapturerFilter> filter = new AudioCapturerFilter();
332     filter->uid = getuid();
333     if (isMicFast_) {
334         filter->capturerInfo.sourceType = SOURCE_TYPE_MIC;
335         filter->capturerInfo.capturerFlags = STREAM_FLAG_FAST;
336     }
337     ret = manager->SelectInputDevice(filter, devices);
338     if (ret == SUCCESS) {
339         isMicRemote_ = !isMicRemote_;
340         cout << "SelectInputDevice success" << endl;
341     } else {
342         cout << "SelectInputDevice failed, ret:" << ret << endl;
343     }
344     return ret;
345 }
346 
StartPlay()347 int32_t PlaybackTest::StartPlay()
348 {
349     if (audioRenderer_ == nullptr) {
350         AUDIO_ERR_LOG("Audiorenderer init failed.");
351         return -1;
352     }
353     if (!audioRenderer_->Start()) {
354         AUDIO_ERR_LOG("Audio renderer start failed.");
355         return -1;
356     }
357     cout << "Start play. current play device: " << isSpkRemote_ << "(0 : local, 1 : remote)" << endl;
358     return 0;
359 }
360 
StopPlay()361 int32_t PlaybackTest::StopPlay()
362 {
363     if (audioRenderer_ == nullptr) {
364         AUDIO_ERR_LOG("Audiorenderer init failed.");
365         return -1;
366     }
367     if (!audioRenderer_->Stop()) {
368         AUDIO_ERR_LOG("Audio renderer stop failed.");
369         return -1;
370     }
371     return 0;
372 }
373 
ReleaseRenderer()374 int32_t PlaybackTest::ReleaseRenderer()
375 {
376     StopPlay();
377     isSpkFast_ = false;
378     if (audioRenderer_ != nullptr && !audioRenderer_->Release()) {
379         AUDIO_ERR_LOG("Audio renderer release failed.");
380         cout << "Audio render release failed" << endl;
381     }
382     audioRenderer_ = nullptr;
383     CloseSpkFile();
384     AUDIO_INFO_LOG("Audio renderer release success.");
385     return 0;
386 }
387 
OnReadData(size_t length)388 void PlaybackTest::OnReadData(size_t length)
389 {
390     BufferDesc bufDesc;
391     if (audioCapturer_ == nullptr) {
392         AUDIO_ERR_LOG("audioCapturer is nullptr.");
393         return;
394     }
395     int32_t ret = audioCapturer_->GetBufferDesc(bufDesc);
396     if (ret != 0 || bufDesc.buffer == nullptr || bufDesc.bufLength == 0) {
397         AUDIO_ERR_LOG("Get buffer desc failed. On read data.");
398         return;
399     }
400     if (micWavFile_ == nullptr) {
401         AUDIO_ERR_LOG("micWavFile_ is nullptr.");
402         return;
403     }
404     size_t cnt = fwrite(bufDesc.buffer, 1, bufDesc.bufLength, micWavFile_);
405     if (cnt != bufDesc.bufLength) {
406         AUDIO_ERR_LOG("fwrite fail, cnt %{public}zu, bufLength %{public}zu.", cnt, bufDesc.bufLength);
407         return;
408     }
409     audioCapturer_->Enqueue(bufDesc);
410 }
411 
OpenMicFile(const std::string & micFilePath)412 bool PlaybackTest::OpenMicFile(const std::string &micFilePath)
413 {
414     if (micWavFile_ != nullptr) {
415         AUDIO_ERR_LOG("Mic file has been opened, micFilePath %{public}s.", micFilePath.c_str());
416         return true;
417     }
418 
419     char path[PATH_MAX] = { 0x00 };
420     if ((strlen(micFilePath.c_str()) > PATH_MAX) || (realpath(micFilePath.c_str(), path) == nullptr)) {
421         AUDIO_ERR_LOG("micFilePath is not valid.");
422         return false;
423     }
424     AUDIO_INFO_LOG("mic path = %{public}s.", path);
425     micWavFile_ = fopen(path, "ab+");
426     if (micWavFile_ == nullptr) {
427         AUDIO_ERR_LOG("Unable to open wave file");
428         return false;
429     }
430     return true;
431 }
432 
CloseMicFile()433 void PlaybackTest::CloseMicFile()
434 {
435     if (micWavFile_ != nullptr) {
436         fclose(micWavFile_);
437         micWavFile_ = nullptr;
438     }
439 }
440 
InitCapturer(bool isFast)441 int32_t PlaybackTest::InitCapturer(bool isFast)
442 {
443     AudioStandard::AudioCapturerOptions capturerOptions = {
444         {
445             AudioStandard::AudioSamplingRate::SAMPLE_RATE_48000,
446             AudioStandard::AudioEncodingType::ENCODING_PCM,
447             AudioStandard::AudioSampleFormat::SAMPLE_S16LE,
448             AudioStandard::AudioChannel::STEREO,
449         },
450         {
451             AudioStandard::SourceType::SOURCE_TYPE_MIC,
452             isFast ? AudioStandard::STREAM_FLAG_FAST : AudioStandard::STREAM_FLAG_NORMAL,
453         }
454     };
455     audioCapturer_ = AudioStandard::AudioCapturer::Create(capturerOptions);
456     if (audioCapturer_ == nullptr) {
457         AUDIO_ERR_LOG("Audio capturer create failed.");
458         return -1;
459     }
460     std::string path = "/data/mic.pcm";
461     OpenMicFile(path);
462     int32_t ret = audioCapturer_->SetCaptureMode(CAPTURE_MODE_CALLBACK);
463     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Set capture mode callback fail, ret %{public}d.", ret);
464     ret = audioCapturer_->SetCapturerReadCallback(shared_from_this());
465     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Client test save data callback fail, ret %{public}d.", ret);
466     AUDIO_INFO_LOG("Audio capturer create success.");
467     isMicFast_ = isFast;
468     return 0;
469 }
470 
StartCapture()471 int32_t PlaybackTest::StartCapture()
472 {
473     if (audioCapturer_ == nullptr) {
474         AUDIO_ERR_LOG("audioCapturer init failed.");
475         return -1;
476     }
477     if (!audioCapturer_->Start()) {
478         AUDIO_ERR_LOG("Audio capture start failed.");
479         return -1;
480     }
481     return 0;
482 }
483 
StopCapture()484 int32_t PlaybackTest::StopCapture()
485 {
486     if (audioCapturer_ == nullptr) {
487         AUDIO_ERR_LOG("audioCapturer init failed.");
488         return -1;
489     }
490     if (!audioCapturer_->Stop()) {
491         AUDIO_ERR_LOG("Audio capture stop failed.");
492         return -1;
493     }
494     return 0;
495 }
496 
ReleaseCapture()497 int32_t PlaybackTest::ReleaseCapture()
498 {
499     isMicFast_ = false;
500     if (audioCapturer_ != nullptr && !audioCapturer_->Release()) {
501         AUDIO_ERR_LOG("Audio capturer release failed.");
502         cout << "Audio capturer release failed" << endl;
503     }
504     audioCapturer_ = nullptr;
505     CloseMicFile();
506     AUDIO_INFO_LOG("Audio capturer release success.");
507     return 0;
508 }
509 using CallTestOptCodeFunc = int32_t (*)(std::shared_ptr<PlaybackTest> playTest);
510 
SetSysPara(const std::string & key,int32_t & value)511 bool SetSysPara(const std::string &key, int32_t &value)
512 {
513     auto res = SetParameter(key.c_str(), std::to_string(value).c_str());
514     if (res < 0) {
515         AUDIO_WARNING_LOG("SetSysPara fail, key:%{public}s res:%{public}d", key.c_str(), res);
516         return false;
517     }
518     AUDIO_INFO_LOG("SetSysPara success.");
519     return true;
520 }
521 
GetUserInput()522 int32_t GetUserInput()
523 {
524     int32_t res = -1; // result
525     size_t count = 3; // try three time
526     cout << ">>";
527     cin >> res;
528     while (cin.fail() && count-- > 0) {
529         cin.clear();
530         cin.ignore();
531         cout << "invalid input, not a number! Please retry with a number." << endl;
532         cout << ">>";
533         cin >> res;
534     }
535     return res;
536 }
537 
PrintUsage()538 void PrintUsage()
539 {
540     cout << "Supported Functionalities:" << endl;
541     cout << "================================Usage=======================================" << endl << endl;
542     cout << "  0: Init local spk." << endl;
543     cout << "  1: Init remote spk." << endl;
544     cout << "  2: Start play." << endl;
545     cout << "  3: Stop play." << endl;
546     cout << "  4: Switch play device between local and remote." << endl;
547     cout << "  5: Release spk." << endl;
548     cout << "  6: Init local mic." << endl;
549     cout << "  7: Init remote mic." << endl;
550     cout << "  8: Start record." << endl;
551     cout << "  9: Stop record." << endl;
552     cout << "  10: Switch record device between local and remote." << endl;
553     cout << "  11: Release mic." << endl;
554     cout << "  12: exit demo." << endl;
555     cout << "  13: Init satellite process with isSatellite is true." << endl;
556     cout << "  14: Init satellite process with isSatellite is false." << endl;
557     cout << " Please input your choice: " << endl;
558 }
559 
InitPlayback(std::shared_ptr<PlaybackTest> playTest,bool isRemote,bool isFast)560 int32_t InitPlayback(std::shared_ptr<PlaybackTest> playTest, bool isRemote, bool isFast)
561 {
562     cout << "Init renderer." << endl;
563     cout << "--isRemote: " << isRemote << "-- --isSpkFast: " << isFast << " --" <<endl;
564     if (playTest == nullptr) {
565         cout << "Play test is nullptr, init spk error." << endl;
566         return -1;
567     }
568     if (isRemote) {
569         cout << "Use remote device, select remote spk." << endl;
570         int32_t ret = playTest->SwitchDevice(OUTPUT_DEVICE);
571         if (ret != 0) {
572             cout << "find no remote device." << endl;
573             return -1;
574         }
575     }
576     int32_t ret = playTest->InitRenderer(isFast);
577     if (ret != 0) {
578         cout << "Init renderer error!" << endl;
579         return -1;
580     }
581     if (isRemote) {
582         playTest->SetSpkRemote(true);
583     }
584     cout << "Init renderer success." << endl << endl;
585     return 0;
586 }
587 
ReleasePlayback(std::shared_ptr<PlaybackTest> playTest)588 int32_t ReleasePlayback(std::shared_ptr<PlaybackTest> playTest)
589 {
590     if (playTest == nullptr) {
591         cout << "Play test is nullptr, release spk error." << endl;
592         return -1;
593     }
594     int32_t ret = playTest->ReleaseRenderer();
595     if (ret != 0) {
596         cout << "Release renderer error!" << endl;
597         return -1;
598     }
599     playTest->SetSpkRemote(false);
600     cout << "Release renderer success." << endl << endl;
601     return 0;
602 }
603 
StartPlay(std::shared_ptr<PlaybackTest> playTest)604 int32_t StartPlay(std::shared_ptr<PlaybackTest> playTest)
605 {
606     if (playTest == nullptr) {
607         cout << "Play test is nullptr, start play error." << endl;
608         return -1;
609     }
610     int32_t ret = playTest->StartPlay();
611     if (ret != 0) {
612         cout << "Start play error!" << endl;
613         return -1;
614     }
615     cout << "Start play success." << endl << endl;
616     return 0;
617 }
618 
StopPlay(std::shared_ptr<PlaybackTest> playTest)619 int32_t StopPlay(std::shared_ptr<PlaybackTest> playTest)
620 {
621     if (playTest == nullptr) {
622         cout << "Play test is nullptr, stop play error." << endl;
623         return -1;
624     }
625     int32_t ret = playTest->StopPlay();
626     if (ret != 0) {
627         cout << "Stop play error!" << endl;
628         return -1;
629     }
630     cout << "Stop play success." << endl << endl;
631     return 0;
632 }
633 
SwitchPlayDevice(std::shared_ptr<PlaybackTest> playTest)634 int32_t SwitchPlayDevice(std::shared_ptr<PlaybackTest> playTest)
635 {
636     if (playTest == nullptr) {
637         cout << "Play test is nullptr, switch play device error." << endl;
638         return -1;
639     }
640     int32_t ret = playTest->SwitchDevice(OUTPUT_DEVICE);
641     if (ret != 0) {
642         cout << "Switch play device error!" << endl;
643         return -1;
644     }
645     cout << "Switch play device success." << endl << endl;
646     return 0;
647 }
648 
InitMic(std::shared_ptr<PlaybackTest> playTest,bool isRemote,bool isFast)649 int32_t InitMic(std::shared_ptr<PlaybackTest> playTest, bool isRemote, bool isFast)
650 {
651     if (playTest == nullptr) {
652         cout << "Play test is nullptr, init mic error." << endl;
653         return -1;
654     }
655     if (isRemote) {
656         cout << "Use remote device, select remote mic." << endl;
657         int32_t ret = playTest->SwitchDevice(INPUT_DEVICE);
658         if (ret != 0) {
659             cout << "find no remote device." << endl;
660             return -1;
661         }
662     }
663     int32_t ret = playTest->InitCapturer(isFast);
664     if (ret != 0) {
665         cout << "Init capturer error!" << endl;
666         return -1;
667     }
668     if (isRemote) {
669         playTest->SetMicRemote(true);
670     }
671     cout << "Init capturer success." << endl << endl;
672     return 0;
673 }
674 
ReleaseMic(std::shared_ptr<PlaybackTest> playTest)675 int32_t ReleaseMic(std::shared_ptr<PlaybackTest> playTest)
676 {
677     if (playTest == nullptr) {
678         cout << "Play test is nullptr, release capturer error." << endl;
679         return -1;
680     }
681     int32_t ret = playTest->ReleaseCapture();
682     if (ret != 0) {
683         cout << "Release capturer error!" << endl;
684         return -1;
685     }
686     playTest->SetMicRemote(false);
687     cout << "Release capturer success." << endl << endl;
688     return 0;
689 }
690 
InitSatelliteProcess(std::shared_ptr<PlaybackTest> playTest,bool satellite)691 int32_t InitSatelliteProcess(std::shared_ptr<PlaybackTest> playTest, bool satellite)
692 {
693     if (playTest == nullptr) {
694         cout << "Play test is nullptr" << endl;
695         return -1;
696     }
697     int32_t ret = playTest->InitSatelliteProcess(satellite);
698     if (ret != 0) {
699         cout << "Start satellite error!" << endl;
700         return -1;
701     }
702     cout << "Start satellite process." << endl << endl;
703     return 0;
704 }
705 
StartCapture(std::shared_ptr<PlaybackTest> playTest)706 int32_t StartCapture(std::shared_ptr<PlaybackTest> playTest)
707 {
708     if (playTest == nullptr) {
709         cout << "Play test is nullptr, start capturer error." << endl;
710         return -1;
711     }
712     int32_t ret = playTest->StartCapture();
713     if (ret != 0) {
714         cout << "Start capturer error!" << endl;
715         return -1;
716     }
717     cout << "Start capturer success." << endl << endl;
718     return 0;
719 }
720 
StopCapture(std::shared_ptr<PlaybackTest> playTest)721 int32_t StopCapture(std::shared_ptr<PlaybackTest> playTest)
722 {
723     if (playTest == nullptr) {
724         cout << "Play test is nullptr, stop capturer error." << endl;
725         return -1;
726     }
727     int32_t ret = playTest->StopCapture();
728     if (ret != 0) {
729         cout << "Stop capturer error!" << endl;
730         return -1;
731     }
732     cout << "Stop capturer success." << endl << endl;
733     return 0;
734 }
735 
SwitchCaptureDevice(std::shared_ptr<PlaybackTest> playTest)736 int32_t SwitchCaptureDevice(std::shared_ptr<PlaybackTest> playTest)
737 {
738     if (playTest == nullptr) {
739         cout << "Play test is nullptr, switch capture device error." << endl;
740         return -1;
741     }
742     int32_t ret = playTest->SwitchDevice(INPUT_DEVICE);
743     if (ret != 0) {
744         cout << "Switch capture device error!" << endl;
745         return -1;
746     }
747     cout << "Switch capture device success." << endl << endl;
748     return 0;
749 }
750 
751 std::map<int32_t, CallTestOptCodeFunc> g_optFuncMap = {
752     {START_SPK, StartPlay},
753     {STOP_SPK, StopPlay},
754     {SWITCH_SPK, SwitchPlayDevice},
755     {RELEASE_SPK, ReleasePlayback},
756     {START_MIC, StartCapture},
757     {STOP_MIC, StopCapture},
758     {SWITCH_MIC, SwitchCaptureDevice},
759     {RELEASE_MIC, ReleaseMic},
760 };
761 
Loop(std::shared_ptr<PlaybackTest> playTest)762 void Loop(std::shared_ptr<PlaybackTest> playTest)
763 {
764     bool isProcTestRun = true;
765     while (isProcTestRun) {
766         PrintUsage();
767         AudioOptCode optCode = INVALID_OPERATION;
768         int32_t res = GetUserInput();
769         if (g_OptStrMap.count(res)) {
770             optCode = static_cast<AudioOptCode>(res);
771         }
772         switch (optCode) {
773             case INIT_LOCAL_SPK:
774                 InitPlayback(playTest, false, false);
775                 break;
776             case INIT_REMOTE_SPK:
777                 InitPlayback(playTest, true, false);
778                 break;
779             case INIT_LOCAL_MIC:
780                 InitMic(playTest, false, false);
781                 break;
782             case INIT_REMOTE_MIC:
783                 InitMic(playTest, true, false);
784                 break;
785             case SATELLITE_ON:
786                 InitSatelliteProcess(playTest, true);
787                 break;
788             case SATELLITE_OFF:
789                 InitSatelliteProcess(playTest, false);
790                 break;
791             case EXIT_DEMO:
792                 ReleasePlayback(playTest);
793                 ReleaseMic(playTest);
794                 isProcTestRun = false;
795                 cout << "exit demo..." << endl;
796                 break;
797             default:
798                 auto it = g_optFuncMap.find(optCode);
799                 if (it != g_optFuncMap.end() && it->second != nullptr) {
800                     CallTestOptCodeFunc &func = it->second;
801                     cout << (*func)(playTest) << endl;
802                     break;
803                 }
804                 cout << "Invalid input: " << optCode << endl;
805                 break;
806         }
807     }
808 }
809 }
810 }
811 
812 using namespace OHOS::AudioStandard;
813 using namespace std;
main(int argc,char * argv[])814 int main(int argc, char* argv[])
815 {
816     cout << "[Fast Audio Stream Test App]" << endl << endl;
817     AUDIO_INFO_LOG("oh fast audio stream test.");
818     std::shared_ptr<PlaybackTest> playTest = std::make_shared<PlaybackTest>();
819     int32_t val = 1;
820     std::string key = "persist.multimedia.audio.mmap.enable";
821     SetSysPara(key, val);
822     Loop(playTest);
823     return 0;
824 }