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