1 /*
2 * Copyright (c) 2022 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
16 #include "fast_audio_renderer_sink.h"
17
18 #include <cstring>
19 #include <dlfcn.h>
20 #include <string>
21 #include <cinttypes>
22 #include <sys/mman.h>
23 #include <unistd.h>
24
25 #include "securec.h"
26
27 #include "audio_errors.h"
28 #include "audio_log.h"
29 #include "audio_utils.h"
30
31 using namespace std;
32
33 namespace OHOS {
34 namespace AudioStandard {
35 namespace {
36 const int32_t HALF_FACTOR = 2;
37 const int32_t MAX_AUDIO_ADAPTER_NUM = 5;
38 const float DEFAULT_VOLUME_LEVEL = 1.0f;
39 const uint32_t AUDIO_CHANNELCOUNT = 2;
40 const uint32_t AUDIO_SAMPLE_RATE_48K = 48000;
41 const uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 3840;
42 const uint32_t INT_32_MAX = 0x7fffffff;
43 const uint32_t PCM_8_BIT = 8;
44 const uint32_t PCM_16_BIT = 16;
45 const uint32_t PCM_24_BIT = 24;
46 const uint32_t PCM_32_BIT = 32;
47 const uint32_t INTERNAL_OUTPUT_STREAM_ID = 0;
48 const int64_t SECOND_TO_NANOSECOND = 1000000000;
49 }
50 #ifdef DUMPFILE
51 const char *g_audioOutTestFilePath = "/data/local/tmp/fast_audio_dump.pcm";
52 #endif // DUMPFILE
53
FastAudioRendererSink()54 FastAudioRendererSink::FastAudioRendererSink()
55 : rendererInited_(false), started_(false), paused_(false), leftVolume_(DEFAULT_VOLUME_LEVEL),
56 rightVolume_(DEFAULT_VOLUME_LEVEL), audioManager_(nullptr), audioAdapter_(nullptr),
57 audioRender_(nullptr)
58 {
59 attr_ = {};
60 #ifdef DUMPFILE
61 pfd = nullptr;
62 #endif // DUMPFILE
63 }
64
~FastAudioRendererSink()65 FastAudioRendererSink::~FastAudioRendererSink()
66 {
67 FastAudioRendererSink::DeInit();
68 }
69
GetInstance()70 FastAudioRendererSink *FastAudioRendererSink::GetInstance()
71 {
72 static FastAudioRendererSink audioRenderer_;
73
74 return &audioRenderer_;
75 }
76
DeInit()77 void FastAudioRendererSink::DeInit()
78 {
79 started_ = false;
80 rendererInited_ = false;
81 if ((audioRender_ != nullptr) && (audioAdapter_ != nullptr)) {
82 audioAdapter_->DestroyRender(audioAdapter_, audioRender_);
83 }
84 audioRender_ = nullptr;
85
86 if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
87 if (routeHandle_ != -1) {
88 audioAdapter_->ReleaseAudioRoute(audioAdapter_, routeHandle_);
89 }
90 audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
91 }
92 audioAdapter_ = nullptr;
93 audioManager_ = nullptr;
94
95 ReleaseMmapBuffer();
96 #ifdef DUMPFILE
97 if (pfd) {
98 fclose(pfd);
99 pfd = nullptr;
100 }
101 #endif // DUMPFILE
102 }
103
InitAttrs(struct AudioSampleAttributes & attrs)104 void InitAttrs(struct AudioSampleAttributes &attrs)
105 {
106 /* Initialization of audio parameters for playback */
107 attrs.channelCount = AUDIO_CHANNELCOUNT;
108 attrs.sampleRate = AUDIO_SAMPLE_RATE_48K;
109 attrs.interleaved = true;
110 attrs.streamId = INTERNAL_OUTPUT_STREAM_ID;
111 attrs.type = AUDIO_MMAP_NOIRQ; // enable mmap!
112 attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
113 attrs.isBigEndian = false;
114 attrs.isSignedData = true;
115 attrs.stopThreshold = INT_32_MAX;
116 attrs.silenceThreshold = 0;
117 }
118
SwitchAdapterRender(struct AudioAdapterDescriptor * descs,string adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort & renderPort,int32_t size)119 static int32_t SwitchAdapterRender(struct AudioAdapterDescriptor *descs, string adapterNameCase,
120 enum AudioPortDirection portFlag, struct AudioPort &renderPort, int32_t size)
121 {
122 if (descs == nullptr) {
123 return ERROR;
124 }
125
126 for (int32_t index = 0; index < size; index++) {
127 struct AudioAdapterDescriptor *desc = &descs[index];
128 if (desc == nullptr || desc->adapterName == nullptr) {
129 continue;
130 }
131 if (!strcmp(desc->adapterName, adapterNameCase.c_str())) {
132 for (uint32_t port = 0; port < desc->portNum; port++) {
133 // Only find out the port of out in the sound card
134 if (desc->ports[port].dir == portFlag) {
135 renderPort = desc->ports[port];
136 return index;
137 }
138 }
139 }
140 }
141 AUDIO_ERR_LOG("SwitchAdapterRender Fail");
142
143 return ERR_INVALID_INDEX;
144 }
145
InitAudioManager()146 int32_t FastAudioRendererSink::InitAudioManager()
147 {
148 AUDIO_INFO_LOG("FastAudioRendererSink: Initialize audio proxy manager");
149
150 audioManager_ = GetAudioManagerFuncs();
151 if (audioManager_ == nullptr) {
152 return ERR_INVALID_HANDLE;
153 }
154
155 return 0;
156 }
157
PcmFormatToBits(enum AudioFormat format)158 uint32_t PcmFormatToBits(enum AudioFormat format)
159 {
160 switch (format) {
161 case AUDIO_FORMAT_PCM_8_BIT:
162 return PCM_8_BIT;
163 case AUDIO_FORMAT_PCM_16_BIT:
164 return PCM_16_BIT;
165 case AUDIO_FORMAT_PCM_24_BIT:
166 return PCM_24_BIT;
167 case AUDIO_FORMAT_PCM_32_BIT:
168 return PCM_32_BIT;
169 default:
170 return PCM_24_BIT;
171 }
172 }
173
GetMmapHandlePosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)174 int32_t FastAudioRendererSink::GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
175 {
176 if (audioRender_ == nullptr) {
177 AUDIO_ERR_LOG("Audio render is null!");
178 return ERR_INVALID_HANDLE;
179 }
180
181 struct AudioTimeStamp timestamp = {};
182 int32_t ret = audioRender_->attr.GetMmapPosition((AudioHandle)audioRender_, &frames, ×tamp);
183 if (ret != 0) {
184 AUDIO_ERR_LOG("Hdi GetMmapPosition filed, ret:%{public}d!", ret);
185 return ERR_OPERATION_FAILED;
186 }
187 alreadyReadFrames_ = frames; // frames already read.
188 curReadPos_ = frameSizeInByte_ * (frames - bufferTotalFrameSize_ * (frames / bufferTotalFrameSize_));
189 CHECK_AND_RETURN_RET_LOG((curReadPos_ >= 0 && curReadPos_ < bufferSize_), ERR_INVALID_PARAM, "curReadPos invalid");
190
191 int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it.
192 if (timestamp.tvSec < 0 || timestamp.tvSec > maxSec || timestamp.tvNSec < 0 ||
193 timestamp.tvNSec > SECOND_TO_NANOSECOND) {
194 AUDIO_ERR_LOG("Hdi GetMmapPosition get invaild second:%{public}" PRId64 " or nanosecond:%{public}" PRId64 " !",
195 timestamp.tvSec, timestamp.tvNSec);
196 return ERR_OPERATION_FAILED;
197 }
198 timeSec = timestamp.tvSec;
199 timeNanoSec = timestamp.tvNSec;
200
201 AUDIO_DEBUG_LOG("GetMmapHandlePosition frames[:%{public}" PRIu64 "] tvsec:%{public}" PRId64 " tvNSec:"
202 "%{public}" PRId64 " alreadyReadFrames:%{public}" PRId64 " curReadPos[%{public}d]",
203 frames, timeSec, timeNanoSec, alreadyReadFrames_, curReadPos_);
204
205 return SUCCESS;
206 }
207
ReleaseMmapBuffer()208 void FastAudioRendererSink::ReleaseMmapBuffer()
209 {
210 if (bufferAddresss_ != nullptr) {
211 munmap(bufferAddresss_, bufferSize_);
212 bufferAddresss_ = nullptr;
213 bufferSize_ = 0;
214 AUDIO_INFO_LOG("ReleaseMmapBuffer end.");
215 } else {
216 AUDIO_WARNING_LOG("ReleaseMmapBuffer buffer already null.");
217 }
218 }
219
PrepareMmapBuffer()220 int32_t FastAudioRendererSink::PrepareMmapBuffer()
221 {
222 int32_t totalBifferInMs = 50; // 5 * (6 + 2 * (2)) = 50ms, the buffer size, not latency.
223 frameSizeInByte_ = PcmFormatToBits(attr_.format) * attr_.channel / PCM_8_BIT;
224 int32_t reqBufferFrameSize = totalBifferInMs * (attr_.sampleRate / 1000);
225
226 struct AudioMmapBufferDescripter desc = {0};
227 int32_t ret = audioRender_->attr.ReqMmapBuffer((AudioHandle)audioRender_, reqBufferFrameSize, &desc);
228 if (ret != 0) {
229 AUDIO_ERR_LOG("ReqMmapBuffer failed, ret:%{public}d", ret);
230 return ERR_OPERATION_FAILED;
231 }
232 AUDIO_INFO_LOG("AudioMmapBufferDescripter memoryAddress[%{private}p] memoryFd[%{public}d] totalBufferFrames"
233 "[%{public}d] transferFrameSize[%{public}d] isShareable[%{public}d] offset[%{public}d]",desc.memoryAddress,
234 desc.memoryFd, desc.totalBufferFrames, desc.transferFrameSize, desc.isShareable , desc.offset);
235
236 bufferFd_ = dup(desc.memoryFd); // fcntl(fd, 1030,3) after dup?
237
238 if (desc.totalBufferFrames < 0 || desc.totalBufferFrames > UINT32_MAX || desc.transferFrameSize < 0 ||
239 desc.transferFrameSize > UINT32_MAX) {
240 AUDIO_ERR_LOG("ReqMmapBuffer invalid values: totalBufferFrames[%{public}d] transferFrameSize[%{public}d]",
241 desc.totalBufferFrames, desc.transferFrameSize);
242 return ERR_OPERATION_FAILED;
243 }
244 bufferTotalFrameSize_ = desc.totalBufferFrames; // 1440 ~ 3840
245 eachReadFrameSize_ = desc.transferFrameSize; // 240
246
247 if (frameSizeInByte_ > ULLONG_MAX / bufferTotalFrameSize_) {
248 AUDIO_ERR_LOG("BufferSize will overflow!");
249 return ERR_OPERATION_FAILED;
250 }
251 bufferSize_ = bufferTotalFrameSize_ * frameSizeInByte_;
252 bufferAddresss_ = (char *)mmap(nullptr, bufferSize_, PROT_READ | PROT_WRITE, MAP_SHARED, bufferFd_, 0);
253 if (bufferAddresss_ == nullptr) {
254 AUDIO_ERR_LOG("mmap buffer failed!");
255 return ERR_OPERATION_FAILED;
256 }
257 return SUCCESS;
258 }
259
260
261
CreateRender(const struct AudioPort & renderPort)262 int32_t FastAudioRendererSink::CreateRender(const struct AudioPort &renderPort)
263 {
264 int32_t ret;
265 struct AudioSampleAttributes param;
266 InitAttrs(param);
267 param.sampleRate = attr_.sampleRate;
268 param.channelCount = attr_.channel;
269 param.format = attr_.format;
270 param.frameSize = PcmFormatToBits(param.format) * param.channelCount / PCM_8_BIT;
271 param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize); // not passed in hdi
272 AUDIO_INFO_LOG("FastAudioRendererSink Create render format: %{public}d", param.format);
273 struct AudioDeviceDescriptor deviceDesc;
274 deviceDesc.portId = renderPort.portId;
275 deviceDesc.pins = PIN_OUT_SPEAKER;
276 deviceDesc.desc = nullptr;
277 ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, ¶m, &audioRender_);
278 if (ret != 0 || audioRender_ == nullptr) {
279 AUDIO_ERR_LOG("AudioDeviceCreateRender failed");
280 audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
281 return ERR_NOT_STARTED;
282 }
283
284 return SUCCESS;
285 }
286
Init(AudioSinkAttr & attr)287 int32_t FastAudioRendererSink::Init(AudioSinkAttr &attr)
288 {
289 AUDIO_INFO_LOG("Init.");
290 attr_ = attr;
291 adapterNameCase_ = attr_.adapterName; // Set sound card information
292 enum AudioPortDirection port = PORT_OUT; // Set port information
293
294 if (InitAudioManager() != 0) {
295 AUDIO_ERR_LOG("Init audio manager Fail");
296 return ERR_NOT_STARTED;
297 }
298
299 int32_t size = 0;
300 int32_t ret;
301 struct AudioAdapterDescriptor *descs = nullptr;
302 ret = audioManager_->GetAllAdapters(audioManager_, &descs, &size);
303 if (size > MAX_AUDIO_ADAPTER_NUM || size == 0 || descs == nullptr || ret != 0) {
304 AUDIO_ERR_LOG("Get adapters Fail");
305 return ERR_NOT_STARTED;
306 }
307
308 int32_t index = SwitchAdapterRender(descs, adapterNameCase_, port, audioPort_, size);
309 if (index < 0) {
310 AUDIO_ERR_LOG("Switch Adapter Fail");
311 return ERR_NOT_STARTED;
312 }
313
314 struct AudioAdapterDescriptor *desc = &descs[index];
315 if (audioManager_->LoadAdapter(audioManager_, desc, &audioAdapter_) != 0) {
316 AUDIO_ERR_LOG("Load Adapter Fail");
317 return ERR_NOT_STARTED;
318 }
319 if (audioAdapter_ == nullptr) {
320 AUDIO_ERR_LOG("Load audio device failed");
321 return ERR_NOT_STARTED;
322 }
323
324 // Initialization port information, can fill through mode and other parameters
325 ret = audioAdapter_->InitAllPorts(audioAdapter_);
326 if (ret != 0) {
327 AUDIO_ERR_LOG("InitAllPorts failed");
328 return ERR_NOT_STARTED;
329 }
330
331 if (CreateRender(audioPort_) != SUCCESS || PrepareMmapBuffer() != SUCCESS) {
332 AUDIO_ERR_LOG("Create render failed, Audio Port: %{public}d", audioPort_.portId);
333 return ERR_NOT_STARTED;
334 }
335
336 rendererInited_ = true;
337
338 #ifdef DUMPFILE
339 pfd = fopen(g_audioOutTestFilePath, "wb+");
340 if (pfd == nullptr) {
341 AUDIO_ERR_LOG("Error opening pcm test file!");
342 }
343 #endif // DUMPFILE
344
345 return SUCCESS;
346 }
347
PreparePosition()348 void FastAudioRendererSink::PreparePosition()
349 {
350 isFirstWrite_ = false;
351 uint64_t frames = 0;
352 int64_t timeSec = 0;
353 int64_t timeNanoSec = 0;
354 GetMmapHandlePosition(frames, timeSec, timeNanoSec); // get first start position
355 int32_t periodByteSize = eachReadFrameSize_ * frameSizeInByte_;
356 if (periodByteSize * writeAheadPeriod_ > ULLONG_MAX - curReadPos_) {
357 AUDIO_ERR_LOG("TempPos will overflow!");
358 return;
359 }
360 size_t tempPos = curReadPos_ + periodByteSize * writeAheadPeriod_; // 1 period ahead
361 curWritePos_ = (tempPos < bufferSize_ ? tempPos : tempPos - bufferSize_);
362 AUDIO_INFO_LOG("First render frame start with curReadPos_[%{public}d] curWritePos_[%{public}d]", curReadPos_,
363 curWritePos_);
364 }
365
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)366 int32_t FastAudioRendererSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
367 {
368 int64_t stamp = GetNowTimeMs();
369 if (audioRender_ == nullptr) {
370 AUDIO_ERR_LOG("Audio Render Handle is nullptr!");
371 return ERR_INVALID_HANDLE;
372 }
373
374 #ifdef DUMPFILE
375 size_t writeResult = fwrite((void*)&data, 1, len, pfd);
376 if (writeResult != len) {
377 AUDIO_ERR_LOG("Failed to write the file.");
378 }
379 #endif // DUMPFILE
380
381 if (len > (bufferSize_ - eachReadFrameSize_ * frameSizeInByte_ * writeAheadPeriod_)) {
382 writeLen = 0;
383 AUDIO_ERR_LOG("RenderFrame failed,too large len[%{public}" PRIu64 "]!", len);
384 return ERR_WRITE_FAILED;
385 }
386
387 if (isFirstWrite_) {
388 PreparePosition();
389 }
390
391 CHECK_AND_RETURN_RET_LOG((curWritePos_ >= 0 && curWritePos_ < bufferSize_), ERR_INVALID_PARAM,
392 "curWritePos_ invalid");
393 char *writePtr = bufferAddresss_ + curWritePos_;
394 uint64_t dataBefore = *(uint64_t *)writePtr;
395 uint64_t dataAfter = 0;
396 uint64_t tempPos = curWritePos_ + len;
397 if (tempPos <= bufferSize_) {
398 if (memcpy_s(writePtr, (bufferSize_ - curWritePos_), static_cast<void *>(&data), len)) {
399 AUDIO_ERR_LOG("copy failed");
400 return ERR_WRITE_FAILED;
401 }
402 dataAfter = *(uint64_t *)writePtr;
403 curWritePos_ = (tempPos == bufferSize_ ? 0 : tempPos);
404 } else {
405 AUDIO_DEBUG_LOG("(tempPos%{public}" PRIu64 ")curWritePos_ + len > bufferSize_", tempPos);
406 size_t writeableSize = bufferSize_ - curWritePos_;
407 if (memcpy_s(writePtr, writeableSize, static_cast<void *>(&data), writeableSize) ||
408 memcpy_s(bufferAddresss_, bufferSize_, static_cast<void *>((char *)&data + writeableSize),
409 (len - writeableSize))) {
410 AUDIO_ERR_LOG("copy failed");
411 return ERR_WRITE_FAILED;
412 }
413 curWritePos_ = len - writeableSize;
414 }
415 writeLen = len;
416
417 stamp = GetNowTimeMs() - stamp;
418 AUDIO_DEBUG_LOG("Render len[%{public}" PRIu64 "] cost[%{public}" PRId64 "]ms curWritePos[%{public}d] dataBefore"
419 "<%{public}" PRIu64 "> dataAfter<%{public}" PRIu64 ">", len, stamp, curWritePos_, dataBefore, dataAfter);
420 return SUCCESS;
421 }
422
Start(void)423 int32_t FastAudioRendererSink::Start(void)
424 {
425 AUDIO_INFO_LOG("Start.");
426 int64_t stamp = GetNowTimeMs();
427 int32_t ret;
428
429 if (audioRender_ == nullptr) {
430 AUDIO_ERR_LOG("FastAudioRendererSink::Start audioRender_ null!");
431 return ERR_INVALID_HANDLE;
432 }
433
434 if (!started_) {
435 ret = audioRender_->control.Start(reinterpret_cast<AudioHandle>(audioRender_));
436 if (ret != 0) {
437 AUDIO_ERR_LOG("FastAudioRendererSink::Start failed!");
438 return ERR_NOT_STARTED;
439 }
440 }
441 started_ = true;
442 AUDIO_DEBUG_LOG("Start cost[%{public}" PRId64 "]ms", GetNowTimeMs() - stamp);
443 return SUCCESS;
444 }
445
SetVolume(float left,float right)446 int32_t FastAudioRendererSink::SetVolume(float left, float right)
447 {
448 int32_t ret;
449 float volume;
450
451 if (audioRender_ == nullptr) {
452 AUDIO_ERR_LOG("FastAudioRendererSink::SetVolume failed audioRender_ null");
453 return ERR_INVALID_HANDLE;
454 }
455
456 leftVolume_ = left;
457 rightVolume_ = right;
458 if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
459 volume = rightVolume_;
460 } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
461 volume = leftVolume_;
462 } else {
463 volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
464 }
465
466 ret = audioRender_->volume.SetVolume(reinterpret_cast<AudioHandle>(audioRender_), volume);
467 if (ret) {
468 AUDIO_ERR_LOG("FastAudioRendererSink::Set volume failed!");
469 }
470
471 return ret;
472 }
473
GetVolume(float & left,float & right)474 int32_t FastAudioRendererSink::GetVolume(float &left, float &right)
475 {
476 left = leftVolume_;
477 right = rightVolume_;
478 return SUCCESS;
479 }
480
SetVoiceVolume(float volume)481 int32_t FastAudioRendererSink::SetVoiceVolume(float volume)
482 {
483 if (audioAdapter_ == nullptr) {
484 AUDIO_ERR_LOG("FastAudioRendererSink: SetVoiceVolume failed audio adapter null");
485 return ERR_INVALID_HANDLE;
486 }
487 AUDIO_DEBUG_LOG("FastAudioRendererSink: SetVoiceVolume %{public}f", volume);
488 return audioAdapter_->SetVoiceVolume(audioAdapter_, volume);
489 }
490
GetLatency(uint32_t * latency)491 int32_t FastAudioRendererSink::GetLatency(uint32_t *latency)
492 {
493 if (audioRender_ == nullptr) {
494 AUDIO_ERR_LOG("FastAudioRendererSink: GetLatency failed audio render null");
495 return ERR_INVALID_HANDLE;
496 }
497
498 if (!latency) {
499 AUDIO_ERR_LOG("FastAudioRendererSink: GetLatency failed latency null");
500 return ERR_INVALID_PARAM;
501 }
502
503 uint32_t hdiLatency;
504 if (audioRender_->GetLatency(audioRender_, &hdiLatency) == 0) {
505 *latency = hdiLatency;
506 return SUCCESS;
507 } else {
508 return ERR_OPERATION_FAILED;
509 }
510 }
511
Stop(void)512 int32_t FastAudioRendererSink::Stop(void)
513 {
514 AUDIO_INFO_LOG("Stop.");
515
516 if (audioRender_ == nullptr) {
517 AUDIO_ERR_LOG("FastAudioRendererSink::Stop failed audioRender_ null");
518 return ERR_INVALID_HANDLE;
519 }
520
521 if (started_) {
522 int32_t ret = audioRender_->control.Stop(reinterpret_cast<AudioHandle>(audioRender_));
523 if (ret != 0) {
524 AUDIO_ERR_LOG("FastAudioRendererSink::Stop failed!");
525 return ERR_OPERATION_FAILED;
526 }
527 }
528 started_ = false;
529
530 return SUCCESS;
531 }
532
Pause(void)533 int32_t FastAudioRendererSink::Pause(void)
534 {
535 int32_t ret;
536
537 if (audioRender_ == nullptr) {
538 AUDIO_ERR_LOG("FastAudioRendererSink::Pause failed audioRender_ null");
539 return ERR_INVALID_HANDLE;
540 }
541
542 if (!started_) {
543 AUDIO_ERR_LOG("FastAudioRendererSink::Pause invalid state!");
544 return ERR_OPERATION_FAILED;
545 }
546
547 if (!paused_) {
548 ret = audioRender_->control.Pause(reinterpret_cast<AudioHandle>(audioRender_));
549 if (ret != 0) {
550 AUDIO_ERR_LOG("FastAudioRendererSink::Pause failed!");
551 return ERR_OPERATION_FAILED;
552 }
553 }
554 paused_ = true;
555
556 return SUCCESS;
557 }
558
Resume(void)559 int32_t FastAudioRendererSink::Resume(void)
560 {
561 int32_t ret;
562
563 if (audioRender_ == nullptr) {
564 AUDIO_ERR_LOG("FastAudioRendererSink::Resume failed audioRender_ null");
565 return ERR_INVALID_HANDLE;
566 }
567
568 if (!started_) {
569 AUDIO_ERR_LOG("FastAudioRendererSink::Resume invalid state!");
570 return ERR_OPERATION_FAILED;
571 }
572
573 if (paused_) {
574 ret = audioRender_->control.Resume(reinterpret_cast<AudioHandle>(audioRender_));
575 if (ret != 0) {
576 AUDIO_ERR_LOG("FastAudioRendererSink::Resume failed!");
577 return ERR_OPERATION_FAILED;
578 }
579 }
580 paused_ = false;
581
582 return SUCCESS;
583 }
584
Reset(void)585 int32_t FastAudioRendererSink::Reset(void)
586 {
587 int32_t ret;
588
589 if (started_ && audioRender_ != nullptr) {
590 ret = audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
591 if (ret != 0) {
592 AUDIO_ERR_LOG("FastAudioRendererSink::Reset failed!");
593 return ERR_OPERATION_FAILED;
594 }
595 }
596
597 return SUCCESS;
598 }
599
Flush(void)600 int32_t FastAudioRendererSink::Flush(void)
601 {
602 int32_t ret;
603
604 if (started_ && audioRender_ != nullptr) {
605 ret = audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
606 if (ret != 0) {
607 AUDIO_ERR_LOG("FastAudioRendererSink::Flush failed!");
608 return ERR_OPERATION_FAILED;
609 }
610 }
611
612 return SUCCESS;
613 }
614 } // namespace AudioStandard
615 } // namespace OHOS
616
617 #ifdef __cplusplus
618 extern "C" {
619 #endif
620
621 using namespace OHOS::AudioStandard;
622
623 FastAudioRendererSink *g_audioRendrSinkInstance = FastAudioRendererSink::GetInstance();
624
FillinFastAudioRenderSinkWapper(const char * deviceNetworkId,void ** wapper)625 int32_t FillinFastAudioRenderSinkWapper(const char *deviceNetworkId, void **wapper)
626 {
627 FastAudioRendererSink *instance = FastAudioRendererSink::GetInstance();
628 if (instance != nullptr) {
629 *wapper = static_cast<void *>(instance);
630 } else {
631 *wapper = nullptr;
632 }
633
634 return SUCCESS;
635 }
636
FastAudioRendererSinkInit(void * wapper,AudioSinkAttr * attr)637 int32_t FastAudioRendererSinkInit(void *wapper, AudioSinkAttr *attr)
638 {
639 (void)wapper;
640 int32_t ret;
641 if (g_audioRendrSinkInstance->rendererInited_) {
642 AUDIO_INFO_LOG("FastAudioRendererSinkInit already inited.");
643 return SUCCESS;
644 }
645
646 ret = g_audioRendrSinkInstance->Init(*attr);
647 return ret;
648 }
649
FastAudioRendererSinkDeInit(void * wapper)650 void FastAudioRendererSinkDeInit(void *wapper)
651 {
652 (void)wapper;
653 if (g_audioRendrSinkInstance->rendererInited_) {
654 g_audioRendrSinkInstance->DeInit();
655 }
656 }
657
FastAudioRendererSinkStop(void * wapper)658 int32_t FastAudioRendererSinkStop(void *wapper)
659 {
660 (void)wapper;
661 int32_t ret;
662
663 if (!g_audioRendrSinkInstance->rendererInited_) {
664 AUDIO_INFO_LOG("FastAudioRendererSinkStop already deinited.");
665 return SUCCESS;
666 }
667
668 ret = g_audioRendrSinkInstance->Stop();
669 return ret;
670 }
671
FastAudioRendererSinkStart(void * wapper)672 int32_t FastAudioRendererSinkStart(void *wapper)
673 {
674 (void)wapper;
675 int32_t ret;
676
677 if (!g_audioRendrSinkInstance->rendererInited_) {
678 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
679 return ERR_NOT_STARTED;
680 }
681
682 ret = g_audioRendrSinkInstance->Start();
683 return ret;
684 }
685
FastAudioRendererSinkPause(void * wapper)686 int32_t FastAudioRendererSinkPause(void *wapper)
687 {
688 (void)wapper;
689 if (!g_audioRendrSinkInstance->rendererInited_) {
690 AUDIO_ERR_LOG("Renderer pause failed");
691 return ERR_NOT_STARTED;
692 }
693
694 return g_audioRendrSinkInstance->Pause();
695 }
696
FastAudioRendererSinkResume(void * wapper)697 int32_t FastAudioRendererSinkResume(void *wapper)
698 {
699 (void)wapper;
700 if (!g_audioRendrSinkInstance->rendererInited_) {
701 AUDIO_ERR_LOG("Renderer resume failed");
702 return ERR_NOT_STARTED;
703 }
704
705 return g_audioRendrSinkInstance->Resume();
706 }
707
FastAudioRendererRenderFrame(void * wapper,char & data,uint64_t len,uint64_t & writeLen)708 int32_t FastAudioRendererRenderFrame(void *wapper, char &data, uint64_t len, uint64_t &writeLen)
709 {
710 (void)wapper;
711 int32_t ret;
712
713 if (!g_audioRendrSinkInstance->rendererInited_) {
714 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
715 return ERR_NOT_STARTED;
716 }
717
718 ret = g_audioRendrSinkInstance->RenderFrame(data, len, writeLen);
719 return ret;
720 }
721
FastAudioRendererSinkSetVolume(void * wapper,float left,float right)722 int32_t FastAudioRendererSinkSetVolume(void *wapper, float left, float right)
723 {
724 (void)wapper;
725 int32_t ret;
726
727 if (!g_audioRendrSinkInstance->rendererInited_) {
728 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
729 return ERR_NOT_STARTED;
730 }
731
732 ret = g_audioRendrSinkInstance->SetVolume(left, right);
733 return ret;
734 }
735
FastAudioRendererSinkGetLatency(void * wapper,uint32_t * latency)736 int32_t FastAudioRendererSinkGetLatency(void *wapper, uint32_t *latency)
737 {
738 (void)wapper;
739 int32_t ret;
740
741 if (!g_audioRendrSinkInstance->rendererInited_) {
742 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
743 return ERR_NOT_STARTED;
744 }
745
746 if (!latency) {
747 AUDIO_ERR_LOG("FastAudioRendererSinkGetLatency failed latency null");
748 return ERR_INVALID_PARAM;
749 }
750
751 ret = g_audioRendrSinkInstance->GetLatency(latency);
752 return ret;
753 }
754
FastAudioRendererSinkGetTransactionId(uint64_t * transactionId)755 int32_t FastAudioRendererSinkGetTransactionId(uint64_t *transactionId)
756 {
757 AUDIO_ERR_LOG("FastAudioRendererSinkGetTransactionId failed transaction id null");
758 return ERR_INVALID_PARAM;
759 }
760 #ifdef __cplusplus
761 }
762 #endif
763