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