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 }