• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &timestamp);
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, &param, &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