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, ¶m, &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