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 #ifndef LOG_TAG
16 #define LOG_TAG "PaStreamTest"
17 #endif
18 
19 #include <chrono>
20 #include <cstdio>
21 #include <cstdlib>
22 #include <cinttypes>
23 #include <unistd.h>
24 #include <thread>
25 #include <random>
26 #include <iostream>
27 #include "securec.h"
28 
29 #include "audio_log.h"
30 #include "audio_renderer.h"
31 #include "audio_capturer.h"
32 #include "pcm2wav.h"
33 
34 using namespace std;
35 namespace OHOS {
36 namespace AudioStandard {
37 constexpr int32_t SAMPLE_FORMAT_U8 = 8;
38 constexpr int32_t SAMPLE_FORMAT_S16LE = 16;
39 constexpr int32_t SAMPLE_FORMAT_S24LE = 24;
40 constexpr int32_t SAMPLE_FORMAT_S32LE = 32;
41 constexpr size_t ONE_READ_FRAME = 3840;
42 
43 enum RendererMode : int32_t {
44     DIRECTLY_WRITE = 0,
45     AFTER_CALLBACK = 1,
46 };
47 
48 enum CapturerMode : int32_t {
49     DIRECTLY_READ = 0,
50     READ_AFTER_CALLBACK = 1,
51 };
52 
53 enum OperationCode : int32_t {
54     CODE_INVALID = -1,
55     RENDERER_CODE_INIT = 0,
56     RENDERER_CODE_START = 1,
57     RENDERER_CODE_PAUSE = 2,
58     RENDERER_CODE_FLUSH = 3,
59     RENDERER_CODE_DRAIN = 4,
60     RENDERER_CODE_STOP = 5,
61     RENDERER_CODE_RELEASE = 6,
62     RENDERER_CODE_WRITE = 7,
63     CAPTURER_CODE_INIT = 100,
64     CAPTURER_CODE_START = 101,
65     CAPTURER_CODE_PAUSE = 102,
66     CAPTURER_CODE_FLUSH = 103,
67     CAPTURER_CODE_STOP = 105,
68     CAPTURER_CODE_RELEASE = 106,
69     CAPTURER_CODE_READ = 107,
70     EXIT_DEMO = 1000,
71 };
72 
73 std::map<int32_t, std::string> g_OptStrMap = {
74     {RENDERER_CODE_INIT, "call spk init process"},
75     {RENDERER_CODE_START, "call start spk process"},
76     {RENDERER_CODE_PAUSE, "call pause spk process"},
77     {RENDERER_CODE_FLUSH, "call flush spk process"},
78     {RENDERER_CODE_DRAIN, "call drain spk process"},
79     {RENDERER_CODE_STOP, "call stop spk process"},
80     {RENDERER_CODE_RELEASE, "release spk process"},
81     {RENDERER_CODE_WRITE, "write data"},
82     {CAPTURER_CODE_INIT, "call capturer init process"},
83     {CAPTURER_CODE_START, "call start capturer process"},
84     {CAPTURER_CODE_PAUSE, "call pause capturer process"},
85     {CAPTURER_CODE_FLUSH, "call flush capturer process"},
86     {CAPTURER_CODE_STOP, "call stop capturer process"},
87     {CAPTURER_CODE_RELEASE, "call release capturer process"},
88     {CAPTURER_CODE_READ, "read data"},
89     {EXIT_DEMO, "exit interactive run test"},
90 };
91 
92 class PaRendererTest : public AudioRendererWriteCallback, public enable_shared_from_this<PaRendererTest> {
93 public:
~PaRendererTest()94     virtual ~PaRendererTest() {};
95     int32_t InitRenderer(RendererMode rendererMode, int32_t fileIndex);
96     int32_t StartPlay();
97     int32_t PausePlay();
98     int32_t FlushPlay();
99     int32_t DrainPlay();
100     int32_t StopPlay();
101     int32_t ReleasePlay();
102     int32_t WriteData();
103     void WriteDataWorker();
104     void OnWriteData(size_t length) override;
105     AudioSampleFormat GetSampleFormat(int32_t wavSampleFormat) const;
106     bool OpenSpkFile(const std::string &spkFilePath);
107     void CloseSpkFile();
108 
109 private:
110     std::unique_ptr<AudioRenderer> audioRenderer_ = nullptr;
111     static constexpr long WAV_HEADER_SIZE = 44;
112     FILE *spkWavFile_ = nullptr;
113     size_t bytesAlreadyWrite_ = 0;
114 
115     std::condition_variable enableWriteCv_;
116     std::mutex enableWriteThreadLock_;
117     bool enableWrite_ = false;
118     int32_t fast_ = 1000;
119     int32_t slow_ = 30000;
120     size_t bufferLength_ = 0;
121     bool isFileOpened_ = false;
122     wav_hdr wavHeader_;
123     RendererMode rendererMode_ = DIRECTLY_WRITE;
124 
125     std::map<int32_t, std::string> filePathMap_ = {
126         {0, "/data/test.wav"},
127         {1, "/data/test2.wav"},
128     };
129 };
130 
GetSampleFormat(int32_t wavSampleFormat) const131 AudioSampleFormat PaRendererTest::GetSampleFormat(int32_t wavSampleFormat) const
132 {
133     switch (wavSampleFormat) {
134         case SAMPLE_FORMAT_U8:
135             return AudioSampleFormat::SAMPLE_U8;
136         case SAMPLE_FORMAT_S16LE:
137             return AudioSampleFormat::SAMPLE_S16LE;
138         case SAMPLE_FORMAT_S24LE:
139             return AudioSampleFormat::SAMPLE_S24LE;
140         case SAMPLE_FORMAT_S32LE:
141             return AudioSampleFormat::SAMPLE_S32LE;
142         default:
143             return AudioSampleFormat::INVALID_WIDTH;
144     }
145 }
146 
OpenSpkFile(const std::string & spkFilePath)147 bool PaRendererTest::OpenSpkFile(const std::string &spkFilePath)
148 {
149     if (spkWavFile_ != nullptr) {
150         AUDIO_ERR_LOG("Spk file has been opened, spkFilePath %{public}s", spkFilePath.c_str());
151         return true;
152     }
153 
154     char path[PATH_MAX] = { 0x00 };
155     if ((strlen(spkFilePath.c_str()) > PATH_MAX) || (realpath(spkFilePath.c_str(), path) == nullptr)) {
156         return false;
157     }
158     AUDIO_INFO_LOG("spk path = %{public}s", path);
159     spkWavFile_ = fopen(path, "rb");
160     if (spkWavFile_ == nullptr) {
161         AUDIO_ERR_LOG("Unable to open wave file");
162         return false;
163     }
164     return true;
165 }
166 
CloseSpkFile()167 void PaRendererTest::CloseSpkFile()
168 {
169     if (spkWavFile_ != nullptr) {
170         fclose(spkWavFile_);
171         spkWavFile_ = nullptr;
172     }
173 }
174 
InitRenderer(RendererMode rendererMode,int32_t fileIndex)175 int32_t PaRendererTest::InitRenderer(RendererMode rendererMode, int32_t fileIndex)
176 {
177     rendererMode_ = rendererMode;
178     AUDIO_INFO_LOG("Start OpenSpkFile, isFileOpened_: %{public}d", isFileOpened_);
179     if (isFileOpened_ == false) {
180         AUDIO_INFO_LOG("Start OpenSpkFile, fileIndex: %{public}d", fileIndex);
181         std::string path = filePathMap_[fileIndex];
182         OpenSpkFile(path);
183 
184         size_t headerSize = sizeof(wav_hdr);
185         size_t bytesRead = fread(&wavHeader_, 1, headerSize, spkWavFile_);
186         AUDIO_DEBUG_LOG("Init renderer, bytesRead: %{public}zu", bytesRead);
187         isFileOpened_ = true;
188     }
189     ContentType contentType = ContentType::CONTENT_TYPE_MUSIC;
190     StreamUsage streamUsage = StreamUsage::STREAM_USAGE_MEDIA;
191 
192     AudioRendererOptions rendererOptions = {};
193     rendererOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
194     rendererOptions.streamInfo.samplingRate = static_cast<AudioSamplingRate>(wavHeader_.SamplesPerSec);
195     rendererOptions.streamInfo.format = GetSampleFormat(wavHeader_.bitsPerSample);
196     rendererOptions.streamInfo.channels = static_cast<AudioChannel>(wavHeader_.NumOfChan);
197     rendererOptions.rendererInfo.contentType = contentType;
198     rendererOptions.rendererInfo.streamUsage = streamUsage;
199     rendererOptions.rendererInfo.rendererFlags = 0;
200     AUDIO_ERR_LOG("samplingRate %{public}d, format %{public}d, channels %{public}d",
201         rendererOptions.streamInfo.samplingRate, rendererOptions.streamInfo.format,
202         rendererOptions.streamInfo.channels);
203     audioRenderer_ = AudioRenderer::Create(rendererOptions);
204     if (audioRenderer_ == nullptr) {
205         AUDIO_ERR_LOG("AudioRendererTest: Create failed");
206         return -1;
207     }
208 
209     if (rendererMode_ == AFTER_CALLBACK) {
210         if (audioRenderer_->SetRenderMode(RENDER_MODE_CALLBACK)) {
211             AUDIO_ERR_LOG("SetRenderMode failed");
212             return false;
213         }
214 
215         if (audioRenderer_->SetRendererWriteCallback(shared_from_this())) {
216             AUDIO_ERR_LOG("SetRendererWriteCallback failed");
217             return false;
218         }
219     }
220 
221     if (audioRenderer_->GetBufferSize(bufferLength_)) {
222         return -1;
223     }
224     AUDIO_INFO_LOG("Audio renderer create success.");
225     return 0;
226 }
227 
StartPlay()228 int32_t PaRendererTest::StartPlay()
229 {
230     if (audioRenderer_ == nullptr) {
231         AUDIO_ERR_LOG("Audiorenderer init failed.");
232         return -1;
233     }
234     if (!audioRenderer_->Start()) {
235         AUDIO_ERR_LOG("Audio renderer start failed.");
236         return -1;
237     }
238     enableWrite_ = true;
239     enableWriteCv_.notify_all();
240     return 0;
241 }
242 
PausePlay()243 int32_t PaRendererTest::PausePlay()
244 {
245     if (audioRenderer_ == nullptr) {
246         AUDIO_ERR_LOG("Audiorenderer init failed.");
247         return -1;
248     }
249     enableWrite_ = false;
250     if (!audioRenderer_->Pause()) {
251         AUDIO_ERR_LOG("Audio renderer start failed.");
252         return -1;
253     }
254     return 0;
255 }
256 
FlushPlay()257 int32_t PaRendererTest::FlushPlay()
258 {
259     if (audioRenderer_ == nullptr) {
260         AUDIO_ERR_LOG("Audiorenderer init failed.");
261         return -1;
262     }
263     if (!audioRenderer_->Flush()) {
264         AUDIO_ERR_LOG("Audio renderer start failed.");
265         return -1;
266     }
267     return 0;
268 }
269 
DrainPlay()270 int32_t PaRendererTest::DrainPlay()
271 {
272     if (audioRenderer_ == nullptr) {
273         AUDIO_ERR_LOG("Audiorenderer init failed.");
274         return -1;
275     }
276     if (!audioRenderer_->Drain()) {
277         AUDIO_ERR_LOG("Audio renderer start failed.");
278         return -1;
279     }
280     return 0;
281 }
282 
StopPlay()283 int32_t PaRendererTest::StopPlay()
284 {
285     if (audioRenderer_ == nullptr) {
286         AUDIO_ERR_LOG("Audiorenderer init failed.");
287         return -1;
288     }
289     enableWrite_ = false;
290     if (!audioRenderer_->Stop()) {
291         AUDIO_ERR_LOG("Audio renderer stop failed.");
292         return -1;
293     }
294     return 0;
295 }
296 
ReleasePlay()297 int32_t PaRendererTest::ReleasePlay()
298 {
299     if (audioRenderer_ == nullptr) {
300         AUDIO_ERR_LOG("Audiorenderer init failed.");
301         return -1;
302     }
303     enableWrite_ = false;
304     if (!audioRenderer_->Release()) {
305         AUDIO_ERR_LOG("Audio renderer stop failed.");
306         return -1;
307     }
308     audioRenderer_ = nullptr;
309     return 0;
310 }
311 
WriteData()312 int32_t PaRendererTest::WriteData()
313 {
314     enableWrite_ = true;
315     std::thread writeDataThread = std::thread(&PaRendererTest::WriteDataWorker, this);
316     writeDataThread.detach();
317     return 0;
318 }
319 
WriteDataWorker()320 void PaRendererTest::WriteDataWorker()
321 {
322     while (true) {
323         std::unique_lock<std::mutex> threadLock(enableWriteThreadLock_);
324         enableWriteCv_.wait(threadLock, [this] {
325             AUDIO_INFO_LOG("enable write state: %{public}d", enableWrite_);
326             return enableWrite_;
327         });
328 
329         std::random_device rd;
330         std::mt19937 gen(rd());
331         std::uniform_int_distribution<> dis(fast_, slow_);
332         int32_t randomNum = dis(gen);
333         AUDIO_INFO_LOG("recorder sleepTime %{public}d", randomNum);
334         usleep(randomNum);
335         if (audioRenderer_ == nullptr) {
336             AUDIO_ERR_LOG("Audiorenderer init failed.");
337             enableWrite_ = false;
338             return ;
339         }
340         if (spkWavFile_ == nullptr) {
341             AUDIO_ERR_LOG("wavFile is nullptr");
342             enableWrite_ = false;
343             return ;
344         }
345         if (feof(spkWavFile_)) {
346             fseek(spkWavFile_, WAV_HEADER_SIZE, SEEK_SET);
347         }
348 
349         if (rendererMode_ == DIRECTLY_WRITE) {
350             auto buffer = std::make_unique<uint8_t[]>(bufferLength_);
351             AUDIO_ERR_LOG("WriteDataWorker: bufferLength_ %{public}zu", bufferLength_);
352             fread(buffer.get(), 1, bufferLength_, spkWavFile_);
353             bytesAlreadyWrite_ += audioRenderer_->Write(buffer.get(), bufferLength_);
354             AUDIO_INFO_LOG("bytesAlreadyWrite_: %{public}zu, bufferLength_: %{public}zu",
355                 bytesAlreadyWrite_, bufferLength_);
356         }
357     }
358 }
359 
OnWriteData(size_t length)360 void PaRendererTest::OnWriteData(size_t length)
361 {
362     AUDIO_INFO_LOG("On write data callback, length %{public}zu", length);
363     BufferDesc currentWriteBuffer = { nullptr, 0, 0};
364     audioRenderer_->GetBufferDesc(currentWriteBuffer);
365     if (currentWriteBuffer.buffer == nullptr) {
366         return  ;
367     }
368     if (length > currentWriteBuffer.bufLength) {
369         currentWriteBuffer.dataLength = currentWriteBuffer.bufLength;
370     } else {
371         currentWriteBuffer.dataLength = length;
372     }
373     fread(currentWriteBuffer.buffer, 1, currentWriteBuffer.dataLength, spkWavFile_);
374     bytesAlreadyWrite_ += currentWriteBuffer.dataLength;
375     audioRenderer_->Enqueue(currentWriteBuffer);
376     AUDIO_INFO_LOG("Callback mode, bytesAlreadyWrite_: %{public}zu, length: %{public}zu",
377         bytesAlreadyWrite_, length);
378 }
379 
380 class PaCapturerTest : public AudioCapturerReadCallback, public enable_shared_from_this<PaCapturerTest> {
381 public:
~PaCapturerTest()382     virtual ~PaCapturerTest() {};
383 
384     int32_t InitCapturer(bool isBlocking, CapturerMode capturerMode);
385     int32_t StartRecorder();
386     int32_t PauseRecorder();
387     int32_t FlushRecorder();
388     int32_t StopRecorder();
389     int32_t ReleaseRecorder();
390     int32_t ReadData();
391     void ReadDataWorker();
392     void OnReadData(size_t length) override;
393 
394 private:
395     std::unique_ptr<AudioCapturer> audioCapturer_ = nullptr;
396     bool isBlocking_ = true;
397 
398     std::condition_variable enableReadCv_;
399     std::mutex enableReadThreadLock_;
400     bool enableRead_ = false;
401     int32_t fast_ = 1; // min sleep time
402     int32_t slow_ = 2; // max sleep time
403     FILE *pfd_ = nullptr;
404     CapturerMode capturerMode_ = DIRECTLY_READ;
405 };
406 
OnReadData(size_t length)407 void PaCapturerTest::OnReadData(size_t length)
408 {
409     AUDIO_INFO_LOG("PaCapturerTest::OnReadData, length: %{public}zu", length);
410     BufferDesc bufferDesc = { nullptr, 0, 0 };
411     audioCapturer_->GetBufferDesc(bufferDesc);
412     fwrite(reinterpret_cast<void *>(bufferDesc.buffer), 1, bufferDesc.bufLength, pfd_);
413     audioCapturer_->Enqueue(bufferDesc);
414 }
415 
InitCapturer(bool isBlocking,CapturerMode capturerMode)416 int32_t PaCapturerTest::InitCapturer(bool isBlocking, CapturerMode capturerMode)
417 {
418     AUDIO_INFO_LOG("Start InitCapturer");
419     isBlocking_ = isBlocking;
420     capturerMode_ = capturerMode;
421     AudioCapturerOptions capturerOptions;
422     capturerOptions.streamInfo.samplingRate = SAMPLE_RATE_8000;
423     capturerOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
424     capturerOptions.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
425     capturerOptions.streamInfo.channels = AudioChannel::STEREO;
426     capturerOptions.capturerInfo.sourceType = SourceType::SOURCE_TYPE_MIC;
427     capturerOptions.capturerInfo.capturerFlags = 0;
428 
429     audioCapturer_ = AudioCapturer::Create(capturerOptions);
430     if (audioCapturer_ == nullptr) {
431         AUDIO_ERR_LOG("Create audioCapturer failed");
432         return -1;
433     }
434     if (capturerMode_ == READ_AFTER_CALLBACK) {
435         if (audioCapturer_->SetCaptureMode(CAPTURE_MODE_CALLBACK)) {
436             AUDIO_ERR_LOG("SetCaptureMode failed");
437             return -1;
438         }
439         if (audioCapturer_->SetCapturerReadCallback(shared_from_this())) {
440             AUDIO_ERR_LOG("SetCapturerReadCallback failed");
441             return -1;
442         }
443     }
444     AUDIO_INFO_LOG("Audio capturer create success.");
445     pfd_ = fopen("/data/data/.pulse_dir/capturer.pcm", "wb+");
446     return 0;
447 }
448 
StartRecorder()449 int32_t PaCapturerTest::StartRecorder()
450 {
451     AUDIO_INFO_LOG("StartRecorder");
452     if (audioCapturer_ == nullptr) {
453         AUDIO_ERR_LOG("audioCapturer_ init failed.");
454         return -1;
455     }
456     enableRead_ = true;
457     enableReadCv_.notify_all();
458     if (!audioCapturer_->Start()) {
459         AUDIO_ERR_LOG("Audio capturer start failed.");
460         return -1;
461     }
462     return 0;
463 }
464 
PauseRecorder()465 int32_t PaCapturerTest::PauseRecorder()
466 {
467     if (audioCapturer_ == nullptr) {
468         AUDIO_ERR_LOG("audioCapturer_ init failed.");
469         return -1;
470     }
471     enableRead_ = false;
472     if (!audioCapturer_->Pause()) {
473         AUDIO_ERR_LOG("Audio capturer start failed.");
474         return -1;
475     }
476     return 0;
477 }
478 
FlushRecorder()479 int32_t PaCapturerTest::FlushRecorder()
480 {
481     if (audioCapturer_ == nullptr) {
482         AUDIO_ERR_LOG("audioCapturer_ init failed.");
483         return -1;
484     }
485     if (!audioCapturer_->Flush()) {
486         AUDIO_ERR_LOG("Audio capturer start failed.");
487         return -1;
488     }
489     return 0;
490 }
491 
StopRecorder()492 int32_t PaCapturerTest::StopRecorder()
493 {
494     if (audioCapturer_ == nullptr) {
495         AUDIO_ERR_LOG("audioCapturer_ init failed.");
496         return -1;
497     }
498     if (!audioCapturer_->Stop()) {
499         AUDIO_ERR_LOG("Audio capturer stop failed.");
500         return -1;
501     }
502     return 0;
503 }
504 
ReleaseRecorder()505 int32_t PaCapturerTest::ReleaseRecorder()
506 {
507     if (audioCapturer_ == nullptr) {
508         AUDIO_ERR_LOG("audioCapturer_ init failed.");
509         return -1;
510     }
511     enableRead_ = false;
512     if (!audioCapturer_->Release()) {
513         AUDIO_ERR_LOG("Audio capturer stop failed.");
514         return -1;
515     }
516     audioCapturer_ = nullptr;
517     fclose(pfd_);
518     pfd_ = nullptr;
519     return 0;
520 }
521 
ReadData()522 int32_t PaCapturerTest::ReadData()
523 {
524     std::thread readDataThread = std::thread(&PaCapturerTest::ReadDataWorker, this);
525     readDataThread.detach();
526     return 0;
527 }
528 
ReadDataWorker()529 void PaCapturerTest::ReadDataWorker()
530 {
531     while (true) {
532         std::unique_lock<std::mutex> threadLock(enableReadThreadLock_);
533         enableReadCv_.wait(threadLock, [this] {
534             AUDIO_INFO_LOG("enable read state: %{public}d", enableRead_);
535             return enableRead_;
536         });
537         AUDIO_INFO_LOG("ReadDataWorker");
538         std::random_device rd;
539         std::mt19937 gen(rd());
540         std::uniform_int_distribution<> dis(fast_, slow_);
541 
542         uint8_t *buffer = reinterpret_cast<uint8_t *>(malloc(ONE_READ_FRAME));
543         memset_s(buffer, ONE_READ_FRAME, 0, ONE_READ_FRAME);
544         int32_t currentReadIndex = 0;
545         while (currentReadIndex < ONE_READ_FRAME) {
546             int32_t len = audioCapturer_->Read(*(buffer + currentReadIndex),
547                 ONE_READ_FRAME - currentReadIndex, isBlocking_);
548             currentReadIndex += len;
549         }
550         fwrite(reinterpret_cast<void *>(buffer), 1, ONE_READ_FRAME, pfd_);
551     }
552 }
553 
GetUserInput()554 int32_t GetUserInput()
555 {
556     int32_t res = -1; // result
557     size_t count = 3; // try three time
558     cout << ">>";
559     cin >> res;
560     while (cin.fail() && count-- > 0) {
561         cin.clear();
562         cin.ignore();
563         cout << "invalid input, not a number! Please retry with a number." << endl;
564         cout << ">>";
565         cin >> res;
566     }
567     return res;
568 }
569 
PrintUsage()570 void PrintUsage()
571 {
572     cout << "[Pa Stream Test App]" << endl << endl;
573     cout << "Supported Functionalities:" << endl;
574     cout << "================================Usage=======================================" << endl << endl;
575     cout << "  0: Init renderer." << endl;
576     cout << "  1: Start play." << endl;
577     cout << "  2: Pause play." << endl;
578     cout << "  3: Flush play." << endl;
579     cout << "  4: Drain play." << endl;
580     cout << "  5: Stop play." << endl;
581     cout << "  6: Release play." << endl;
582     cout << "  7: Write data run." << endl;
583 
584     cout << "  100: Init Capturer." << endl;
585     cout << "  101: Start read." << endl;
586     cout << "  102: Pause read." << endl;
587     cout << "  103: Flush read." << endl;
588     cout << "  105: Stop read." << endl;
589     cout << "  106: Release read." << endl;
590     cout << "  107: Read data run." << endl;
591 
592     cout << "  1000: exit demo." << endl;
593     cout << " Please input your choice: " << endl;
594 }
595 
InitPlayback(std::shared_ptr<PaRendererTest> streamTest,RendererMode rendererMode,int32_t fileIndex)596 int32_t InitPlayback(std::shared_ptr<PaRendererTest> streamTest, RendererMode rendererMode, int32_t fileIndex)
597 {
598     if (streamTest == nullptr) {
599         cout << "PaRendererTest obj is nullptr, init spk error." << endl;
600         return -1;
601     }
602     int32_t ret = streamTest->InitRenderer(rendererMode, fileIndex);
603     if (ret != 0) {
604         cout << "Init renderer error!" << endl;
605         return -1;
606     }
607     return 0;
608 }
609 
StartPlay(std::shared_ptr<PaRendererTest> streamTest)610 int32_t StartPlay(std::shared_ptr<PaRendererTest> streamTest)
611 {
612     if (streamTest == nullptr) {
613         cout << "PaRendererTest obj is nullptr, start play error." << endl;
614         return -1;
615     }
616     int32_t ret = streamTest->StartPlay();
617     if (ret != 0) {
618         cout << "Start play error!" << endl;
619         return -1;
620     }
621     return 0;
622 }
623 
PausePlay(std::shared_ptr<PaRendererTest> streamTest)624 int32_t PausePlay(std::shared_ptr<PaRendererTest> streamTest)
625 {
626     if (streamTest == nullptr) {
627         cout << "PaRendererTest obj is nullptr, pause play error." << endl;
628         return -1;
629     }
630     int32_t ret = streamTest->PausePlay();
631     if (ret != 0) {
632         cout << "Pause play error!" << endl;
633         return -1;
634     }
635     return 0;
636 }
637 
FlushPlay(std::shared_ptr<PaRendererTest> streamTest)638 int32_t FlushPlay(std::shared_ptr<PaRendererTest> streamTest)
639 {
640     if (streamTest == nullptr) {
641         cout << "PaRendererTest obj is nullptr, Flush play error." << endl;
642         return -1;
643     }
644     int32_t ret = streamTest->FlushPlay();
645     if (ret != 0) {
646         cout << "Flush play error!" << endl;
647         return -1;
648     }
649     return 0;
650 }
651 
DrainPlay(std::shared_ptr<PaRendererTest> streamTest)652 int32_t DrainPlay(std::shared_ptr<PaRendererTest> streamTest)
653 {
654     if (streamTest == nullptr) {
655         cout << "PaRendererTest obj is nullptr, Drain play error." << endl;
656         return -1;
657     }
658     int32_t ret = streamTest->DrainPlay();
659     if (ret != 0) {
660         cout << "Drain play error!" << endl;
661         return -1;
662     }
663     return 0;
664 }
665 
StopPlay(std::shared_ptr<PaRendererTest> streamTest)666 int32_t StopPlay(std::shared_ptr<PaRendererTest> streamTest)
667 {
668     if (streamTest == nullptr) {
669         cout << "PaRendererTest obj is nullptr, stop play error." << endl;
670         return -1;
671     }
672     int32_t ret = streamTest->StopPlay();
673     if (ret != 0) {
674         cout << "Stop play error!" << endl;
675         return -1;
676     }
677     return 0;
678 }
679 
ReleasePlay(std::shared_ptr<PaRendererTest> streamTest)680 int32_t ReleasePlay(std::shared_ptr<PaRendererTest> streamTest)
681 {
682     if (streamTest == nullptr) {
683         cout << "PaRendererTest obj is nullptr, stop play error." << endl;
684         return -1;
685     }
686     int32_t ret = streamTest->ReleasePlay();
687     if (ret != 0) {
688         cout << "Stop play error!" << endl;
689         return -1;
690     }
691     return 0;
692 }
693 
WriteData(std::shared_ptr<PaRendererTest> streamTest)694 int32_t WriteData(std::shared_ptr<PaRendererTest> streamTest)
695 {
696     if (streamTest == nullptr) {
697         cout << "PaRendererTest obj is nullptr, stop play error." << endl;
698         return -1;
699     }
700     int32_t ret = streamTest->WriteData();
701     if (ret != 0) {
702         cout << "Stop play error!" << endl;
703         return -1;
704     }
705     return 0;
706 }
707 
InitRecorder(std::shared_ptr<PaCapturerTest> capturerTest,bool isBlocking,CapturerMode capturerMode)708 int32_t InitRecorder(std::shared_ptr<PaCapturerTest> capturerTest, bool isBlocking, CapturerMode capturerMode)
709 {
710     if (capturerTest == nullptr) {
711         cout << "PaRendererTest obj is nullptr, init recorder error." << endl;
712         return -1;
713     }
714     int32_t ret = capturerTest->InitCapturer(isBlocking, capturerMode);
715     if (ret != 0) {
716         cout << "Init capturer error!" << endl;
717         return -1;
718     }
719     return 0;
720 }
721 
StartRecorder(std::shared_ptr<PaCapturerTest> capturerTest)722 int32_t StartRecorder(std::shared_ptr<PaCapturerTest> capturerTest)
723 {
724     if (capturerTest == nullptr) {
725         cout << "PaRendererTest obj is nullptr, start recorder error." << endl;
726         return -1;
727     }
728     int32_t ret = capturerTest->StartRecorder();
729     if (ret != 0) {
730         cout << "Start recorder error!" << endl;
731         return -1;
732     }
733     return 0;
734 }
735 
PauseRecorder(std::shared_ptr<PaCapturerTest> capturerTest)736 int32_t PauseRecorder(std::shared_ptr<PaCapturerTest> capturerTest)
737 {
738     if (capturerTest == nullptr) {
739         cout << "PaRendererTest obj is nullptr, pause recorder error." << endl;
740         return -1;
741     }
742     int32_t ret = capturerTest->PauseRecorder();
743     if (ret != 0) {
744         cout << "Pause recorder error!" << endl;
745         return -1;
746     }
747     return 0;
748 }
749 
FlushRecorder(std::shared_ptr<PaCapturerTest> capturerTest)750 int32_t FlushRecorder(std::shared_ptr<PaCapturerTest> capturerTest)
751 {
752     if (capturerTest == nullptr) {
753         cout << "PaRendererTest obj is nullptr, Flush recorder error." << endl;
754         return -1;
755     }
756     int32_t ret = capturerTest->FlushRecorder();
757     if (ret != 0) {
758         cout << "Flush recorder error!" << endl;
759         return -1;
760     }
761     return 0;
762 }
763 
StopRecorder(std::shared_ptr<PaCapturerTest> capturerTest)764 int32_t StopRecorder(std::shared_ptr<PaCapturerTest> capturerTest)
765 {
766     if (capturerTest == nullptr) {
767         cout << "PaRendererTest obj is nullptr, stop recorder error." << endl;
768         return -1;
769     }
770     int32_t ret = capturerTest->StopRecorder();
771     if (ret != 0) {
772         cout << "Stop recorder error!" << endl;
773         return -1;
774     }
775     return 0;
776 }
777 
ReleaseRecorder(std::shared_ptr<PaCapturerTest> capturerTest)778 int32_t ReleaseRecorder(std::shared_ptr<PaCapturerTest> capturerTest)
779 {
780     if (capturerTest == nullptr) {
781         cout << "PaRendererTest obj is nullptr, stop recorder error." << endl;
782         return -1;
783     }
784     int32_t ret = capturerTest->ReleaseRecorder();
785     if (ret != 0) {
786         cout << "Stop recorder error!" << endl;
787         return -1;
788     }
789     return 0;
790 }
791 
ReadData(std::shared_ptr<PaCapturerTest> capturerTest)792 int32_t ReadData(std::shared_ptr<PaCapturerTest> capturerTest)
793 {
794     if (capturerTest == nullptr) {
795         cout << "PaCapturerTest obj is nullptr, read data error." << endl;
796         return -1;
797     }
798     int32_t ret = capturerTest->ReadData();
799     if (ret != 0) {
800         cout << "Read data error!" << endl;
801         return -1;
802     }
803     return 0;
804 }
805 
HandleCapturerCode(OperationCode optCode,std::shared_ptr<PaRendererTest> streamTest,std::shared_ptr<PaCapturerTest> capturerTest)806 void HandleCapturerCode(OperationCode optCode, std::shared_ptr<PaRendererTest> streamTest,
807     std::shared_ptr<PaCapturerTest> capturerTest)
808 {
809     switch (optCode) {
810         case RENDERER_CODE_START:
811             StartPlay(streamTest);
812             break;
813         case RENDERER_CODE_PAUSE:
814             PausePlay(streamTest);
815             break;
816         case RENDERER_CODE_FLUSH:
817             FlushPlay(streamTest);
818             break;
819         case RENDERER_CODE_DRAIN:
820             DrainPlay(streamTest);
821             break;
822         case RENDERER_CODE_STOP:
823             StopPlay(streamTest);
824             break;
825         case RENDERER_CODE_RELEASE:
826             ReleasePlay(streamTest);
827             break;
828         case RENDERER_CODE_WRITE:
829             WriteData(streamTest);
830             break;
831         case CAPTURER_CODE_START:
832             StartRecorder(capturerTest);
833             break;
834         case CAPTURER_CODE_PAUSE:
835             PauseRecorder(capturerTest);
836             break;
837         case CAPTURER_CODE_FLUSH:
838             FlushRecorder(capturerTest);
839             break;
840         case CAPTURER_CODE_STOP:
841             StopRecorder(capturerTest);
842             break;
843         case CAPTURER_CODE_RELEASE:
844             ReleaseRecorder(capturerTest);
845             break;
846         case CAPTURER_CODE_READ:
847             ReadData(capturerTest);
848             break;
849         default:
850             cout << "Invalid input: " << optCode << endl;
851             break;
852     }
853 }
854 
Loop(std::shared_ptr<PaRendererTest> streamTest,std::shared_ptr<PaCapturerTest> capturerTest)855 void Loop(std::shared_ptr<PaRendererTest> streamTest, std::shared_ptr<PaCapturerTest> capturerTest)
856 {
857     bool isProcTestRun = true;
858     while (isProcTestRun) {
859         PrintUsage();
860         OperationCode optCode = CODE_INVALID;
861         int32_t res = GetUserInput();
862         int32_t fileIndex = -1;
863         int32_t rendererMode = 0;
864         int32_t isBlocking = 0;
865         int32_t capturerMode = 0;
866 
867         if (g_OptStrMap.count(res)) {
868             optCode = static_cast<OperationCode>(res);
869         }
870         switch (optCode) {
871             case RENDERER_CODE_INIT:
872                 rendererMode = GetUserInput();
873                 fileIndex = GetUserInput();
874                 InitPlayback(streamTest, static_cast<RendererMode>(rendererMode), fileIndex);
875                 break;
876             // Capturer
877             case CAPTURER_CODE_INIT:
878                 isBlocking = GetUserInput();
879                 capturerMode = GetUserInput();
880                 InitRecorder(capturerTest, isBlocking, static_cast<CapturerMode>(capturerMode));
881                 break;
882             case EXIT_DEMO:
883                 isProcTestRun = false;
884                 break;
885             default:
886                 HandleCapturerCode(optCode, streamTest, capturerTest);
887                 break;
888         }
889     }
890 }
891 }
892 }
893 
894 using namespace OHOS::AudioStandard;
895 using namespace std;
main(int argc,char * argv[])896 int main(int argc, char* argv[])
897 {
898     cout << "oh pa stream test." << endl;
899     std::shared_ptr<PaRendererTest> streamTest = std::make_shared<PaRendererTest>();
900     std::shared_ptr<PaCapturerTest> capturerTest = std::make_shared<PaCapturerTest>();
901 
902     Loop(streamTest, capturerTest);
903     streamTest->CloseSpkFile();
904     return 0;
905 }