• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 <cstring>
17 #include <dlfcn.h>
18 #include <string>
19 #include <unistd.h>
20 
21 #include "audio_errors.h"
22 #include "media_log.h"
23 #include "audio_renderer_sink.h"
24 
25 using namespace std;
26 
27 namespace OHOS {
28 namespace AudioStandard {
29 namespace {
30 const int32_t HALF_FACTOR = 2;
31 const int32_t MAX_AUDIO_ADAPTER_NUM = 4;
32 const float DEFAULT_VOLUME_LEVEL = 1.0f;
33 const uint32_t AUDIO_CHANNELCOUNT = 2;
34 const uint32_t AUDIO_SAMPLE_RATE_48K = 48000;
35 const uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 4096;
36 const uint32_t INT_32_MAX = 0x7fffffff;
37 const uint32_t PCM_8_BIT = 8;
38 const uint32_t PCM_16_BIT = 16;
39 const uint32_t PCM_24_BIT = 24;
40 const uint32_t PCM_32_BIT = 32;
41 const uint32_t INTERNAL_OUTPUT_STREAM_ID = 0;
42 }
43 
44 #ifdef DUMPFILE
45 const char *g_audioOutTestFilePath = "/data/local/tmp/audioout_test.pcm";
46 #endif // DUMPFILE
47 
AudioRendererSink()48 AudioRendererSink::AudioRendererSink()
49     : rendererInited_(false), started_(false), paused_(false), leftVolume_(DEFAULT_VOLUME_LEVEL),
50       rightVolume_(DEFAULT_VOLUME_LEVEL), audioManager_(nullptr), audioAdapter_(nullptr), audioRender_(nullptr)
51 {
52     attr_ = {};
53 #ifdef DUMPFILE
54     pfd = nullptr;
55 #endif // DUMPFILE
56 }
57 
~AudioRendererSink()58 AudioRendererSink::~AudioRendererSink()
59 {
60     DeInit();
61 }
62 
GetInstance()63 AudioRendererSink *AudioRendererSink::GetInstance()
64 {
65     static AudioRendererSink audioRenderer_;
66 
67     return &audioRenderer_;
68 }
69 
DeInit()70 void AudioRendererSink::DeInit()
71 {
72     started_ = false;
73     rendererInited_ = false;
74     if ((audioRender_ != nullptr) && (audioAdapter_ != nullptr)) {
75         audioAdapter_->DestroyRender(audioAdapter_, audioRender_);
76     }
77     audioRender_ = nullptr;
78 
79     if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
80         if (routeHandle_ != -1) {
81             audioAdapter_->ReleaseAudioRoute(audioAdapter_, routeHandle_);
82         }
83         audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
84     }
85     audioAdapter_ = nullptr;
86     audioManager_ = nullptr;
87 #ifdef DUMPFILE
88     if (pfd) {
89         fclose(pfd);
90         pfd = nullptr;
91     }
92 #endif // DUMPFILE
93 }
94 
InitAttrs(struct AudioSampleAttributes & attrs)95 void InitAttrs(struct AudioSampleAttributes &attrs)
96 {
97     /* Initialization of audio parameters for playback */
98 #ifdef PRODUCT_M40
99     attrs.format = AUDIO_FORMAT_PCM_32_BIT;
100     attrs.frameSize = PCM_32_BIT * attrs.channelCount / PCM_8_BIT;
101 #else
102     attrs.format = AUDIO_FORMAT_PCM_16_BIT;
103     attrs.frameSize = PCM_16_BIT * attrs.channelCount / PCM_8_BIT;
104 #endif
105     attrs.channelCount = AUDIO_CHANNELCOUNT;
106     attrs.sampleRate = AUDIO_SAMPLE_RATE_48K;
107     attrs.interleaved = true;
108     attrs.streamId = INTERNAL_OUTPUT_STREAM_ID;
109     attrs.type = AUDIO_IN_MEDIA;
110     attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
111     attrs.isBigEndian = false;
112     attrs.isSignedData = true;
113     attrs.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (attrs.frameSize);
114     attrs.stopThreshold = INT_32_MAX;
115     attrs.silenceThreshold = 0;
116 }
117 
SwitchAdapterRender(struct AudioAdapterDescriptor * descs,string adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort & renderPort,int32_t size)118 static int32_t SwitchAdapterRender(struct AudioAdapterDescriptor *descs, string adapterNameCase,
119     enum AudioPortDirection portFlag, struct AudioPort &renderPort, int32_t size)
120 {
121     if (descs == nullptr) {
122         return ERROR;
123     }
124 
125     for (int32_t index = 0; index < size; index++) {
126         struct AudioAdapterDescriptor *desc = &descs[index];
127         if (desc == nullptr || desc->adapterName == nullptr) {
128             continue;
129         }
130         if (!strcmp(desc->adapterName, adapterNameCase.c_str())) {
131             for (uint32_t port = 0; port < desc->portNum; port++) {
132                 // Only find out the port of out in the sound card
133                 if (desc->ports[port].dir == portFlag) {
134                     renderPort = desc->ports[port];
135                     return index;
136                 }
137             }
138         }
139     }
140     MEDIA_ERR_LOG("SwitchAdapterRender Fail");
141 
142     return ERR_INVALID_INDEX;
143 }
144 
InitAudioManager()145 int32_t AudioRendererSink::InitAudioManager()
146 {
147     MEDIA_INFO_LOG("AudioRendererSink: Initialize audio proxy manager");
148 
149     audioManager_ = GetAudioProxyManagerFuncs();
150     if (audioManager_ == nullptr) {
151         return ERR_INVALID_HANDLE;
152     }
153 
154     return 0;
155 }
156 
PcmFormatToBits(enum AudioFormat format)157 uint32_t PcmFormatToBits(enum AudioFormat format)
158 {
159     switch (format) {
160         case AUDIO_FORMAT_PCM_8_BIT:
161             return PCM_8_BIT;
162         case AUDIO_FORMAT_PCM_16_BIT:
163             return PCM_16_BIT;
164         case AUDIO_FORMAT_PCM_24_BIT:
165             return PCM_24_BIT;
166         case AUDIO_FORMAT_PCM_32_BIT:
167             return PCM_32_BIT;
168         default:
169             return PCM_24_BIT;
170     }
171 }
172 
CreateRender(struct AudioPort & renderPort)173 int32_t AudioRendererSink::CreateRender(struct AudioPort &renderPort)
174 {
175     int32_t ret;
176     struct AudioSampleAttributes param;
177     InitAttrs(param);
178     param.sampleRate = attr_.sampleRate;
179     param.channelCount = attr_.channel;
180     param.format = attr_.format;
181     param.frameSize = PcmFormatToBits(param.format) * param.channelCount / PCM_8_BIT;
182     param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
183     MEDIA_INFO_LOG("AudioRendererSink Create render format: %{public}d", param.format);
184     struct AudioDeviceDescriptor deviceDesc;
185     deviceDesc.portId = renderPort.portId;
186     deviceDesc.pins = PIN_OUT_SPEAKER;
187     deviceDesc.desc = nullptr;
188     ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, &param, &audioRender_);
189     if (ret != 0 || audioRender_ == nullptr) {
190         MEDIA_ERR_LOG("AudioDeviceCreateRender failed");
191         audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
192         return ERR_NOT_STARTED;
193     }
194 
195     return 0;
196 }
197 
GetAndLoadAdapter(void)198 int32_t AudioRendererSink::GetAndLoadAdapter(void)
199 {
200 #ifdef PRODUCT_M40
201     string adapterNameCase = "internal";  // Set sound card information
202 #elif (defined (PRODUCT_Hi37XX))
203     string adapterNameCase = "primary";  // Set sound card information
204 #else
205     string adapterNameCase = "usb";  // Set sound card information
206 #endif
207     enum AudioPortDirection port = PORT_OUT; // Set port information
208     int32_t size = 0;
209     struct AudioAdapterDescriptor *descs = nullptr;
210     int32_t ret = audioManager_->GetAllAdapters(audioManager_, &descs, &size);
211     if (size > MAX_AUDIO_ADAPTER_NUM || size == 0 || descs == nullptr || ret != 0) {
212         MEDIA_ERR_LOG("Get adapters Fail");
213         return ERR_NOT_STARTED;
214     }
215 
216     // Get qualified sound card and port
217     int32_t index = SwitchAdapterRender(descs, adapterNameCase, port, audioPort_, size);
218     if (index < 0) {
219         MEDIA_ERR_LOG("Switch Adapter Fail");
220         return ERR_NOT_STARTED;
221     }
222 
223     struct AudioAdapterDescriptor *desc = &descs[index];
224     if (audioManager_->LoadAdapter(audioManager_, desc, &audioAdapter_) != 0) {
225         MEDIA_ERR_LOG("Load Adapter Fail");
226         return ERR_NOT_STARTED;
227     }
228     if (audioAdapter_ == nullptr) {
229         MEDIA_ERR_LOG("Load audio device failed");
230         return ERR_NOT_STARTED;
231     }
232     return SUCCESS;
233 }
234 
Init(AudioSinkAttr & attr)235 int32_t AudioRendererSink::Init(AudioSinkAttr &attr)
236 {
237     attr_ = attr;
238 
239     if (InitAudioManager() != 0) {
240         MEDIA_ERR_LOG("Init audio manager Fail");
241         return ERR_NOT_STARTED;
242     }
243 
244     int32_t ret = GetAndLoadAdapter();
245     if (ret != SUCCESS) {
246         return ret;
247     }
248 
249     // Initialization port information, can fill through mode and other parameters
250     ret = audioAdapter_->InitAllPorts(audioAdapter_);
251     if (ret != 0) {
252         MEDIA_ERR_LOG("InitAllPorts failed");
253         return ERR_NOT_STARTED;
254     }
255 
256     if (CreateRender(audioPort_) != 0) {
257         MEDIA_ERR_LOG("Create render failed, Audio Port: %{public}d", audioPort_.portId);
258         return ERR_NOT_STARTED;
259     }
260 
261 #ifdef PRODUCT_M40
262     ret = OpenOutput(DEVICE_TYPE_SPEAKER);
263     if (ret < 0) {
264         MEDIA_ERR_LOG("AudioRendererSink: Update route FAILED: %{public}d", ret);
265     }
266 #endif
267 
268     rendererInited_ = true;
269 
270 #ifdef DUMPFILE
271     pfd = fopen(g_audioOutTestFilePath, "wb+");
272     if (pfd == nullptr) {
273         MEDIA_ERR_LOG("Error opening pcm test file!");
274     }
275 #endif // DUMPFILE
276 
277     return SUCCESS;
278 }
279 
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)280 int32_t AudioRendererSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
281 {
282     int32_t ret;
283     if (audioRender_ == nullptr) {
284         MEDIA_ERR_LOG("Audio Render Handle is nullptr!");
285         return ERR_INVALID_HANDLE;
286     }
287 
288 #ifdef DUMPFILE
289     size_t writeResult = fwrite((void*)&data, 1, len, pfd);
290     if (writeResult != len) {
291         MEDIA_ERR_LOG("Failed to write the file.");
292     }
293 #endif // DUMPFILE
294 
295     ret = audioRender_->RenderFrame(audioRender_, (void*)&data, len, &writeLen);
296     if (ret != 0) {
297         MEDIA_ERR_LOG("RenderFrame failed ret: %{public}x", ret);
298         return ERR_WRITE_FAILED;
299     }
300 
301     return SUCCESS;
302 }
303 
Start(void)304 int32_t AudioRendererSink::Start(void)
305 {
306     int32_t ret;
307 
308     if (!started_) {
309         ret = audioRender_->control.Start(reinterpret_cast<AudioHandle>(audioRender_));
310         if (!ret) {
311             started_ = true;
312             return SUCCESS;
313         } else {
314             MEDIA_ERR_LOG("AudioRendererSink::Start failed!");
315             return ERR_NOT_STARTED;
316         }
317     }
318 
319     return SUCCESS;
320 }
321 
SetVolume(float left,float right)322 int32_t AudioRendererSink::SetVolume(float left, float right)
323 {
324     int32_t ret;
325     float volume;
326 
327     if (audioRender_ == nullptr) {
328         MEDIA_ERR_LOG("AudioRendererSink::SetVolume failed audioRender_ null");
329         return ERR_INVALID_HANDLE;
330     }
331 
332     leftVolume_ = left;
333     rightVolume_ = right;
334     if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
335         volume = rightVolume_;
336     } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
337         volume = leftVolume_;
338     } else {
339         volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
340     }
341 
342     ret = audioRender_->volume.SetVolume(reinterpret_cast<AudioHandle>(audioRender_), volume);
343     if (ret) {
344         MEDIA_ERR_LOG("AudioRendererSink::Set volume failed!");
345     }
346 
347     return ret;
348 }
349 
GetVolume(float & left,float & right)350 int32_t AudioRendererSink::GetVolume(float &left, float &right)
351 {
352     left = leftVolume_;
353     right = rightVolume_;
354     return SUCCESS;
355 }
356 
GetLatency(uint32_t * latency)357 int32_t AudioRendererSink::GetLatency(uint32_t *latency)
358 {
359     if (audioRender_ == nullptr) {
360         MEDIA_ERR_LOG("AudioRendererSink: GetLatency failed audio render null");
361         return ERR_INVALID_HANDLE;
362     }
363 
364     if (!latency) {
365         MEDIA_ERR_LOG("AudioRendererSink: GetLatency failed latency null");
366         return ERR_INVALID_PARAM;
367     }
368 
369     uint32_t hdiLatency;
370     if (audioRender_->GetLatency(audioRender_, &hdiLatency) == 0) {
371         *latency = hdiLatency;
372         return SUCCESS;
373     } else {
374         return ERR_OPERATION_FAILED;
375     }
376 }
377 
378 #ifdef PRODUCT_M40
GetAudioCategory(AudioScene audioScene)379 static AudioCategory GetAudioCategory(AudioScene audioScene)
380 {
381     AudioCategory audioCategory;
382     switch (audioScene) {
383         case AUDIO_SCENE_DEFAULT:
384             audioCategory = AUDIO_IN_MEDIA;
385             break;
386         case AUDIO_SCENE_RINGING:
387             audioCategory = AUDIO_IN_RINGTONE;
388             break;
389         case AUDIO_SCENE_PHONE_CALL:
390             audioCategory = AUDIO_IN_CALL;
391             break;
392         case AUDIO_SCENE_PHONE_CHAT:
393             audioCategory = AUDIO_IN_COMMUNICATION;
394             break;
395         default:
396             audioCategory = AUDIO_IN_MEDIA;
397             break;
398     }
399     MEDIA_DEBUG_LOG("AudioRendererSink: Audio category returned is: %{public}d", audioCategory);
400 
401     return audioCategory;
402 }
403 #endif
404 
SetOutputPortPin(DeviceType outputDevice,AudioRouteNode & sink)405 static int32_t SetOutputPortPin(DeviceType outputDevice, AudioRouteNode &sink)
406 {
407     int32_t ret = SUCCESS;
408 
409     switch (outputDevice) {
410         case DEVICE_TYPE_SPEAKER:
411             sink.ext.device.type = PIN_OUT_SPEAKER;
412             sink.ext.device.desc = "pin_out_speaker";
413             break;
414         case DEVICE_TYPE_WIRED_HEADSET:
415             sink.ext.device.type = PIN_OUT_HEADSET;
416             sink.ext.device.desc = "pin_out_headset";
417             break;
418         case DEVICE_TYPE_USB_HEADSET:
419             sink.ext.device.type = PIN_OUT_USB_EXT;
420             sink.ext.device.desc = "pin_out_usb_ext";
421             break;
422         default:
423             ret = ERR_NOT_SUPPORTED;
424             break;
425     }
426 
427     return ret;
428 }
429 
OpenOutput(DeviceType outputDevice)430 int32_t AudioRendererSink::OpenOutput(DeviceType outputDevice)
431 {
432     AudioRouteNode source = {};
433     AudioRouteNode sink = {};
434 
435     int32_t ret = SetOutputPortPin(outputDevice, sink);
436     if (ret != SUCCESS) {
437         MEDIA_ERR_LOG("AudioRendererSink: OpenOutput FAILED: %{public}d", ret);
438         return ret;
439     }
440 
441     source.portId = 0;
442     source.role = AUDIO_PORT_SOURCE_ROLE;
443     source.type = AUDIO_PORT_MIX_TYPE;
444     source.ext.mix.moduleId = 0;
445     source.ext.mix.streamId = INTERNAL_OUTPUT_STREAM_ID;
446 
447     sink.portId = audioPort_.portId;
448     sink.role = AUDIO_PORT_SINK_ROLE;
449     sink.type = AUDIO_PORT_DEVICE_TYPE;
450     sink.ext.device.moduleId = 0;
451 
452     AudioRoute route = {
453         .sourcesNum = 1,
454         .sources = &source,
455         .sinksNum = 1,
456         .sinks = &sink,
457     };
458 
459     ret = audioAdapter_->UpdateAudioRoute(audioAdapter_, &route, &routeHandle_);
460     MEDIA_DEBUG_LOG("AudioRendererSink: UpdateAudioRoute returns: %{public}d", ret);
461     if (ret != 0) {
462         MEDIA_ERR_LOG("AudioRendererSink: UpdateAudioRoute failed");
463         return ERR_OPERATION_FAILED;
464     }
465 
466     return SUCCESS;
467 }
468 
SetAudioScene(AudioScene audioScene)469 int32_t AudioRendererSink::SetAudioScene(AudioScene audioScene)
470 {
471     MEDIA_INFO_LOG("AudioRendererSink::SetAudioScene in");
472     CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene <= AUDIO_SCENE_PHONE_CHAT,
473                              ERR_INVALID_PARAM, "invalid audioScene");
474     if (audioRender_ == nullptr) {
475         MEDIA_ERR_LOG("AudioRendererSink::SetAudioScene failed audio render handle is null!");
476         return ERR_INVALID_HANDLE;
477     }
478 
479 #ifdef PRODUCT_M40
480     int32_t ret = OpenOutput(DEVICE_TYPE_SPEAKER);
481     if (ret < 0) {
482         MEDIA_ERR_LOG("AudioRendererSink: Update route FAILED: %{public}d", ret);
483     }
484 
485     struct AudioSceneDescriptor scene;
486     scene.scene.id = GetAudioCategory(audioScene);
487     scene.desc.pins = PIN_OUT_SPEAKER;
488     if (audioRender_->scene.SelectScene == nullptr) {
489         MEDIA_ERR_LOG("AudioRendererSink: Select scene nullptr");
490         return ERR_OPERATION_FAILED;
491     }
492 
493     ret = audioRender_->scene.SelectScene((AudioHandle)audioRender_, &scene);
494     if (ret < 0) {
495         MEDIA_ERR_LOG("AudioRendererSink: Select scene FAILED: %{public}d", ret);
496         return ERR_OPERATION_FAILED;
497     }
498 #endif
499 
500     MEDIA_INFO_LOG("AudioRendererSink::Select audio scene SUCCESS: %{public}d", audioScene);
501     return SUCCESS;
502 }
503 
Stop(void)504 int32_t AudioRendererSink::Stop(void)
505 {
506     int32_t ret;
507 
508     if (audioRender_ == nullptr) {
509         MEDIA_ERR_LOG("AudioRendererSink::Stop failed audioRender_ null");
510         return ERR_INVALID_HANDLE;
511     }
512 
513     if (started_) {
514         ret = audioRender_->control.Stop(reinterpret_cast<AudioHandle>(audioRender_));
515         if (!ret) {
516             started_ = false;
517             return SUCCESS;
518         } else {
519             MEDIA_ERR_LOG("AudioRendererSink::Stop failed!");
520             return ERR_OPERATION_FAILED;
521         }
522     }
523 
524     return SUCCESS;
525 }
526 
Pause(void)527 int32_t AudioRendererSink::Pause(void)
528 {
529     int32_t ret;
530 
531     if (audioRender_ == nullptr) {
532         MEDIA_ERR_LOG("AudioRendererSink::Pause failed audioRender_ null");
533         return ERR_INVALID_HANDLE;
534     }
535 
536     if (!started_) {
537         MEDIA_ERR_LOG("AudioRendererSink::Pause invalid state!");
538         return ERR_OPERATION_FAILED;
539     }
540 
541     if (!paused_) {
542         ret = audioRender_->control.Pause(reinterpret_cast<AudioHandle>(audioRender_));
543         if (!ret) {
544             paused_ = true;
545             return SUCCESS;
546         } else {
547             MEDIA_ERR_LOG("AudioRendererSink::Pause failed!");
548             return ERR_OPERATION_FAILED;
549         }
550     }
551 
552     return SUCCESS;
553 }
554 
Resume(void)555 int32_t AudioRendererSink::Resume(void)
556 {
557     int32_t ret;
558 
559     if (audioRender_ == nullptr) {
560         MEDIA_ERR_LOG("AudioRendererSink::Resume failed audioRender_ null");
561         return ERR_INVALID_HANDLE;
562     }
563 
564     if (!started_) {
565         MEDIA_ERR_LOG("AudioRendererSink::Resume invalid state!");
566         return ERR_OPERATION_FAILED;
567     }
568 
569     if (paused_) {
570         ret = audioRender_->control.Resume(reinterpret_cast<AudioHandle>(audioRender_));
571         if (!ret) {
572             paused_ = false;
573             return SUCCESS;
574         } else {
575             MEDIA_ERR_LOG("AudioRendererSink::Resume failed!");
576             return ERR_OPERATION_FAILED;
577         }
578     }
579 
580     return SUCCESS;
581 }
582 
Reset(void)583 int32_t AudioRendererSink::Reset(void)
584 {
585     int32_t ret;
586 
587     if (started_ && audioRender_ != nullptr) {
588         ret = audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
589         if (!ret) {
590             return SUCCESS;
591         } else {
592             MEDIA_ERR_LOG("AudioRendererSink::Reset failed!");
593             return ERR_OPERATION_FAILED;
594         }
595     }
596 
597     return ERR_OPERATION_FAILED;
598 }
599 
Flush(void)600 int32_t AudioRendererSink::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) {
607             return SUCCESS;
608         } else {
609             MEDIA_ERR_LOG("AudioRendererSink::Flush failed!");
610             return ERR_OPERATION_FAILED;
611         }
612     }
613 
614     return ERR_OPERATION_FAILED;
615 }
616 } // namespace AudioStandard
617 } // namespace OHOS
618 
619 #ifdef __cplusplus
620 extern "C" {
621 #endif
622 
623 using namespace OHOS::AudioStandard;
624 
625 AudioRendererSink *g_audioRendrSinkInstance = AudioRendererSink::GetInstance();
626 
AudioRendererSinkInit(AudioSinkAttr * attr)627 int32_t AudioRendererSinkInit(AudioSinkAttr *attr)
628 {
629     int32_t ret;
630 
631     if (g_audioRendrSinkInstance->rendererInited_)
632         return SUCCESS;
633 
634     ret = g_audioRendrSinkInstance->Init(*attr);
635     return ret;
636 }
637 
AudioRendererSinkDeInit()638 void AudioRendererSinkDeInit()
639 {
640     if (g_audioRendrSinkInstance->rendererInited_)
641         g_audioRendrSinkInstance->DeInit();
642 }
643 
AudioRendererSinkStop()644 int32_t AudioRendererSinkStop()
645 {
646     int32_t ret;
647 
648     if (!g_audioRendrSinkInstance->rendererInited_)
649         return SUCCESS;
650 
651     ret = g_audioRendrSinkInstance->Stop();
652     return ret;
653 }
654 
AudioRendererSinkStart()655 int32_t AudioRendererSinkStart()
656 {
657     int32_t ret;
658 
659     if (!g_audioRendrSinkInstance->rendererInited_) {
660         MEDIA_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
661         return ERR_NOT_STARTED;
662     }
663 
664     ret = g_audioRendrSinkInstance->Start();
665     return ret;
666 }
667 
AudioRendererRenderFrame(char & data,uint64_t len,uint64_t & writeLen)668 int32_t AudioRendererRenderFrame(char &data, uint64_t len, uint64_t &writeLen)
669 {
670     int32_t ret;
671 
672     if (!g_audioRendrSinkInstance->rendererInited_) {
673         MEDIA_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
674         return ERR_NOT_STARTED;
675     }
676 
677     ret = g_audioRendrSinkInstance->RenderFrame(data, len, writeLen);
678     return ret;
679 }
680 
AudioRendererSinkSetVolume(float left,float right)681 int32_t AudioRendererSinkSetVolume(float left, float right)
682 {
683     int32_t ret;
684 
685     if (!g_audioRendrSinkInstance->rendererInited_) {
686         MEDIA_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
687         return ERR_NOT_STARTED;
688     }
689 
690     ret = g_audioRendrSinkInstance->SetVolume(left, right);
691     return ret;
692 }
693 
AudioRendererSinkGetLatency(uint32_t * latency)694 int32_t AudioRendererSinkGetLatency(uint32_t *latency)
695 {
696     int32_t ret;
697 
698     if (!g_audioRendrSinkInstance->rendererInited_) {
699         MEDIA_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
700         return ERR_NOT_STARTED;
701     }
702 
703     if (!latency) {
704         MEDIA_ERR_LOG("AudioRendererSinkGetLatency failed latency null");
705         return ERR_INVALID_PARAM;
706     }
707 
708     ret = g_audioRendrSinkInstance->GetLatency(latency);
709     return ret;
710 }
711 #ifdef __cplusplus
712 }
713 #endif
714