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 #include <cinttypes>
21 #include "audio_errors.h"
22 #include "audio_log.h"
23 #include "audio_utils.h"
24 #include "audio_renderer_sink.h"
25 #include "power_mgr_client.h"
26
27 using namespace std;
28
29 namespace OHOS {
30 namespace AudioStandard {
31 namespace {
32 const int32_t HALF_FACTOR = 2;
33 const int32_t MAX_AUDIO_ADAPTER_NUM = 5;
34 const float DEFAULT_VOLUME_LEVEL = 1.0f;
35 const uint32_t AUDIO_CHANNELCOUNT = 2;
36 const uint32_t AUDIO_SAMPLE_RATE_48K = 48000;
37 const uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 4096;
38 const uint32_t INT_32_MAX = 0x7fffffff;
39 const uint32_t PCM_8_BIT = 8;
40 const uint32_t PCM_16_BIT = 16;
41 const uint32_t PCM_24_BIT = 24;
42 const uint32_t PCM_32_BIT = 32;
43 const uint32_t INTERNAL_OUTPUT_STREAM_ID = 0;
44 const uint32_t PARAM_VALUE_LENTH = 10;
45 const uint32_t STEREO_CHANNEL_COUNT = 2;
46 }
47 #ifdef DUMPFILE
48 // Note: accessing to this directory requires selinux permission
49 const char *g_audioOutTestFilePath = "/data/local/tmp/audioout_test.pcm";
50 #endif // DUMPFILE
51
AudioRendererSink()52 AudioRendererSink::AudioRendererSink()
53 : rendererInited_(false), started_(false), paused_(false), leftVolume_(DEFAULT_VOLUME_LEVEL),
54 rightVolume_(DEFAULT_VOLUME_LEVEL), openSpeaker_(0), audioManager_(nullptr), audioAdapter_(nullptr),
55 audioRender_(nullptr)
56 {
57 attr_ = {};
58 #ifdef DUMPFILE
59 pfd = nullptr;
60 #endif // DUMPFILE
61 }
62
~AudioRendererSink()63 AudioRendererSink::~AudioRendererSink()
64 {
65 AUDIO_ERR_LOG("~AudioRendererSinkInner");
66 }
67
GetInstance()68 AudioRendererSink *AudioRendererSink::GetInstance()
69 {
70 static AudioRendererSink audioRenderer_;
71
72 return &audioRenderer_;
73 }
74
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)75 void AudioRendererSink::SetAudioParameter(const AudioParamKey key, const std::string& condition,
76 const std::string& value)
77 {
78 AUDIO_INFO_LOG("SetAudioParameter:key %{public}d, condition: %{public}s, value: %{public}s", key,
79 condition.c_str(), value.c_str());
80 AudioExtParamKey hdiKey = AudioExtParamKey(key);
81 if (audioAdapter_ == nullptr) {
82 AUDIO_ERR_LOG("SetAudioParameter failed, audioAdapter_ is null");
83 return;
84 }
85 int32_t ret = audioAdapter_->SetExtraParams(audioAdapter_, hdiKey, condition.c_str(), value.c_str());
86 if (ret != SUCCESS) {
87 AUDIO_ERR_LOG("SetAudioParameter failed, error code: %d", ret);
88 }
89 }
90
GetAudioParameter(const AudioParamKey key,const std::string & condition)91 std::string AudioRendererSink::GetAudioParameter(const AudioParamKey key, const std::string& condition)
92 {
93 AUDIO_INFO_LOG("GetAudioParameter: key %{public}d, condition: %{public}s", key, condition.c_str());
94 AudioExtParamKey hdiKey = AudioExtParamKey(key);
95 char value[PARAM_VALUE_LENTH];
96 if (audioAdapter_ == nullptr) {
97 AUDIO_ERR_LOG("GetAudioParameter failed, audioAdapter_ is null");
98 return "";
99 }
100 int32_t ret = audioAdapter_->GetExtraParams(audioAdapter_, hdiKey, condition.c_str(), value, PARAM_VALUE_LENTH);
101 if (ret != SUCCESS) {
102 AUDIO_ERR_LOG("GetAudioParameter failed, error code: %d", ret);
103 return "";
104 }
105 return value;
106 }
107
SetAudioMonoState(bool audioMono)108 void AudioRendererSink::SetAudioMonoState(bool audioMono)
109 {
110 audioMonoState_ = audioMono;
111 }
112
SetAudioBalanceValue(float audioBalance)113 void AudioRendererSink::SetAudioBalanceValue(float audioBalance)
114 {
115 // reset the balance coefficient value firstly
116 leftBalanceCoef_ = 1.0f;
117 rightBalanceCoef_ = 1.0f;
118
119 if (std::abs(audioBalance - 0.0f) <= std::numeric_limits<float>::epsilon()) {
120 // audioBalance is equal to 0.0f
121 audioBalanceState_ = false;
122 } else {
123 // audioBalance is not equal to 0.0f
124 audioBalanceState_ = true;
125 // calculate the balance coefficient
126 if (audioBalance > 0.0f) {
127 leftBalanceCoef_ -= audioBalance;
128 } else if (audioBalance < 0.0f) {
129 rightBalanceCoef_ += audioBalance;
130 }
131 }
132 }
133
AdjustStereoToMono(char * data,uint64_t len)134 void AudioRendererSink::AdjustStereoToMono(char *data, uint64_t len)
135 {
136 if (attr_.channel != STEREO_CHANNEL_COUNT) {
137 // only stereo is surpported now (stereo channel count is 2)
138 AUDIO_ERR_LOG("AudioRendererSink::AdjustStereoToMono: Unsupported channel number. Channel: %{public}d",
139 attr_.channel);
140 return;
141 }
142
143 switch (attr_.format) {
144 case AUDIO_FORMAT_PCM_8_BIT: {
145 // this function needs to be further tested for usability
146 AdjustStereoToMonoForPCM8Bit(reinterpret_cast<int8_t *>(data), len);
147 break;
148 }
149 case AUDIO_FORMAT_PCM_16_BIT: {
150 AdjustStereoToMonoForPCM16Bit(reinterpret_cast<int16_t *>(data), len);
151 break;
152 }
153 case AUDIO_FORMAT_PCM_24_BIT: {
154 // this function needs to be further tested for usability
155 AdjustStereoToMonoForPCM24Bit(reinterpret_cast<int8_t *>(data), len);
156 break;
157 }
158 case AUDIO_FORMAT_PCM_32_BIT: {
159 AdjustStereoToMonoForPCM32Bit(reinterpret_cast<int32_t *>(data), len);
160 break;
161 }
162 default: {
163 // if the audio format is unsupported, the audio data will not be changed
164 AUDIO_ERR_LOG("AudioRendererSink::AdjustStereoToMono: Unsupported audio format");
165 break;
166 }
167 }
168 }
169
AdjustAudioBalance(char * data,uint64_t len)170 void AudioRendererSink::AdjustAudioBalance(char *data, uint64_t len)
171 {
172 if (attr_.channel != STEREO_CHANNEL_COUNT) {
173 // only stereo is surpported now (stereo channel count is 2)
174 AUDIO_ERR_LOG("AudioRendererSink::AdjustAudioBalance: Unsupported channel number. Channel: %{public}d",
175 attr_.channel);
176 return;
177 }
178
179 switch (attr_.format) {
180 case AUDIO_FORMAT_PCM_8_BIT: {
181 // this function needs to be further tested for usability
182 AdjustAudioBalanceForPCM8Bit(reinterpret_cast<int8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
183 break;
184 }
185 case AUDIO_FORMAT_PCM_16_BIT: {
186 AdjustAudioBalanceForPCM16Bit(reinterpret_cast<int16_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
187 break;
188 }
189 case AUDIO_FORMAT_PCM_24_BIT: {
190 // this function needs to be further tested for usability
191 AdjustAudioBalanceForPCM24Bit(reinterpret_cast<int8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
192 break;
193 }
194 case AUDIO_FORMAT_PCM_32_BIT: {
195 AdjustAudioBalanceForPCM32Bit(reinterpret_cast<int32_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
196 break;
197 }
198 default: {
199 // if the audio format is unsupported, the audio data will not be changed
200 AUDIO_ERR_LOG("AudioRendererSink::AdjustAudioBalance: Unsupported audio format");
201 break;
202 }
203 }
204 }
205
DeInit()206 void AudioRendererSink::DeInit()
207 {
208 AUDIO_INFO_LOG("DeInit.");
209 started_ = false;
210 rendererInited_ = false;
211 if ((audioRender_ != nullptr) && (audioAdapter_ != nullptr)) {
212 audioAdapter_->DestroyRender(audioAdapter_, audioRender_);
213 }
214 audioRender_ = nullptr;
215
216 if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
217 audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
218 }
219 audioAdapter_ = nullptr;
220 audioManager_ = nullptr;
221 #ifdef DUMPFILE
222 if (pfd) {
223 fclose(pfd);
224 pfd = nullptr;
225 }
226 #endif // DUMPFILE
227 }
228
InitAttrs(struct AudioSampleAttributes & attrs)229 void InitAttrs(struct AudioSampleAttributes &attrs)
230 {
231 /* Initialization of audio parameters for playback */
232 attrs.channelCount = AUDIO_CHANNELCOUNT;
233 attrs.sampleRate = AUDIO_SAMPLE_RATE_48K;
234 attrs.interleaved = true;
235 attrs.streamId = INTERNAL_OUTPUT_STREAM_ID;
236 attrs.type = AUDIO_IN_MEDIA;
237 attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
238 attrs.isBigEndian = false;
239 attrs.isSignedData = true;
240 attrs.stopThreshold = INT_32_MAX;
241 attrs.silenceThreshold = 0;
242 }
243
SwitchAdapterRender(struct AudioAdapterDescriptor * descs,string adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort & renderPort,int32_t size)244 static int32_t SwitchAdapterRender(struct AudioAdapterDescriptor *descs, string adapterNameCase,
245 enum AudioPortDirection portFlag, struct AudioPort &renderPort, int32_t size)
246 {
247 if (descs == nullptr) {
248 return ERROR;
249 }
250
251 for (int32_t index = 0; index < size; index++) {
252 struct AudioAdapterDescriptor *desc = &descs[index];
253 if (desc == nullptr || desc->adapterName == nullptr) {
254 continue;
255 }
256 if (!strcmp(desc->adapterName, adapterNameCase.c_str())) {
257 for (uint32_t port = 0; port < desc->portNum; port++) {
258 // Only find out the port of out in the sound card
259 if (desc->ports[port].dir == portFlag) {
260 renderPort = desc->ports[port];
261 return index;
262 }
263 }
264 }
265 }
266 AUDIO_ERR_LOG("SwitchAdapterRender Fail");
267
268 return ERR_INVALID_INDEX;
269 }
270
InitAudioManager()271 int32_t AudioRendererSink::InitAudioManager()
272 {
273 AUDIO_INFO_LOG("AudioRendererSink: Initialize audio proxy manager");
274
275 audioManager_ = GetAudioManagerFuncs();
276 if (audioManager_ == nullptr) {
277 return ERR_INVALID_HANDLE;
278 }
279
280 return 0;
281 }
282
PcmFormatToBits(enum AudioFormat format)283 uint32_t PcmFormatToBits(enum AudioFormat format)
284 {
285 switch (format) {
286 case AUDIO_FORMAT_PCM_8_BIT:
287 return PCM_8_BIT;
288 case AUDIO_FORMAT_PCM_16_BIT:
289 return PCM_16_BIT;
290 case AUDIO_FORMAT_PCM_24_BIT:
291 return PCM_24_BIT;
292 case AUDIO_FORMAT_PCM_32_BIT:
293 return PCM_32_BIT;
294 default:
295 AUDIO_INFO_LOG("PcmFormatToBits: Unkown format type,set it to default");
296 return PCM_24_BIT;
297 }
298 }
299
CreateRender(const struct AudioPort & renderPort)300 int32_t AudioRendererSink::CreateRender(const struct AudioPort &renderPort)
301 {
302 int32_t ret;
303 struct AudioSampleAttributes param;
304 InitAttrs(param);
305 param.sampleRate = attr_.sampleRate;
306 param.channelCount = attr_.channel;
307 param.format = attr_.format;
308 param.frameSize = PcmFormatToBits(param.format) * param.channelCount / PCM_8_BIT;
309 param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
310 AUDIO_INFO_LOG("AudioRendererSink Create render format: %{public}d", param.format);
311 struct AudioDeviceDescriptor deviceDesc;
312 deviceDesc.portId = renderPort.portId;
313 deviceDesc.desc = nullptr;
314 deviceDesc.pins = PIN_OUT_SPEAKER;
315 ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, ¶m, &audioRender_);
316 if (ret != 0 || audioRender_ == nullptr) {
317 AUDIO_ERR_LOG("AudioDeviceCreateRender failed.");
318 audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
319 return ERR_NOT_STARTED;
320 }
321
322 return 0;
323 }
324
Init(AudioSinkAttr & attr)325 int32_t AudioRendererSink::Init(AudioSinkAttr &attr)
326 {
327 attr_ = attr;
328 adapterNameCase_ = attr_.adapterName; // Set sound card information
329 openSpeaker_ = attr_.openMicSpeaker;
330 enum AudioPortDirection port = PORT_OUT; // Set port information
331
332 if (InitAudioManager() != 0) {
333 AUDIO_ERR_LOG("Init audio manager Fail.");
334 return ERR_NOT_STARTED;
335 }
336
337 int32_t size = 0;
338 int32_t ret;
339 struct AudioAdapterDescriptor *descs = nullptr;
340 ret = audioManager_->GetAllAdapters(audioManager_, &descs, &size);
341 if (size > MAX_AUDIO_ADAPTER_NUM || size == 0 || descs == nullptr || ret != 0) {
342 AUDIO_ERR_LOG("Get adapters Fail.");
343 return ERR_NOT_STARTED;
344 }
345
346 // Get qualified sound card and port
347 int32_t index = SwitchAdapterRender(descs, adapterNameCase_, port, audioPort_, size);
348 if (index < 0) {
349 AUDIO_ERR_LOG("Switch Adapter Fail.");
350 return ERR_NOT_STARTED;
351 }
352
353 struct AudioAdapterDescriptor *desc = &descs[index];
354 if (audioManager_->LoadAdapter(audioManager_, desc, &audioAdapter_) != 0) {
355 AUDIO_ERR_LOG("Load Adapter Fail.");
356 return ERR_NOT_STARTED;
357 }
358 if (audioAdapter_ == nullptr) {
359 AUDIO_ERR_LOG("Load audio device failed.");
360 return ERR_NOT_STARTED;
361 }
362
363 // Initialization port information, can fill through mode and other parameters
364 ret = audioAdapter_->InitAllPorts(audioAdapter_);
365 if (ret != 0) {
366 AUDIO_ERR_LOG("InitAllPorts failed");
367 return ERR_NOT_STARTED;
368 }
369
370 if (CreateRender(audioPort_) != 0) {
371 AUDIO_ERR_LOG("Create render failed, Audio Port: %{public}d", audioPort_.portId);
372 return ERR_NOT_STARTED;
373 }
374 if (openSpeaker_) {
375 ret = SetOutputRoute(DEVICE_TYPE_SPEAKER);
376 if (ret < 0) {
377 AUDIO_ERR_LOG("AudioRendererSink: Update route FAILED: %{public}d", ret);
378 }
379 }
380 rendererInited_ = true;
381
382 #ifdef DUMPFILE
383 pfd = fopen(g_audioOutTestFilePath, "wb+");
384 if (pfd == nullptr) {
385 AUDIO_ERR_LOG("Error opening pcm test file!");
386 }
387 #endif // DUMPFILE
388
389 return SUCCESS;
390 }
391
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)392 int32_t AudioRendererSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
393 {
394 int64_t stamp = GetNowTimeMs();
395 int32_t ret;
396 if (audioRender_ == nullptr) {
397 AUDIO_ERR_LOG("Audio Render Handle is nullptr!");
398 return ERR_INVALID_HANDLE;
399 }
400
401 if (audioMonoState_) {
402 AdjustStereoToMono(&data, len);
403 }
404
405 if (audioBalanceState_) {
406 AdjustAudioBalance(&data, len);
407 }
408
409 #ifdef DUMPFILE
410 size_t writeResult = fwrite((void*)&data, 1, len, pfd);
411 if (writeResult != len) {
412 AUDIO_ERR_LOG("Failed to write the file.");
413 }
414 #endif // DUMPFILE
415
416 ret = audioRender_->RenderFrame(audioRender_, static_cast<void*>(&data), len, &writeLen);
417 if (ret != 0) {
418 AUDIO_ERR_LOG("RenderFrame failed ret: %{public}x", ret);
419 return ERR_WRITE_FAILED;
420 }
421
422 stamp = GetNowTimeMs() - stamp;
423 AUDIO_DEBUG_LOG("RenderFrame len[%{public}" PRIu64 "] cost[%{public}" PRId64 "]ms", len, stamp);
424 return SUCCESS;
425 }
426
Start(void)427 int32_t AudioRendererSink::Start(void)
428 {
429 AUDIO_INFO_LOG("Start.");
430
431 if (mKeepRunningLock == nullptr) {
432 mKeepRunningLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock("AudioPrimaryBackgroundPlay",
433 PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND);
434 }
435
436 if (mKeepRunningLock != nullptr) {
437 AUDIO_INFO_LOG("AudioRendererSink call KeepRunningLock lock");
438 mKeepRunningLock->Lock(0); // 0 for lasting.
439 } else {
440 AUDIO_ERR_LOG("mKeepRunningLock is null, playback can not work well!");
441 }
442
443 int32_t ret;
444 if (!started_) {
445 ret = audioRender_->control.Start(reinterpret_cast<AudioHandle>(audioRender_));
446 if (!ret) {
447 started_ = true;
448 return SUCCESS;
449 } else {
450 AUDIO_ERR_LOG("AudioRendererSink::Start failed!");
451 return ERR_NOT_STARTED;
452 }
453 }
454
455 return SUCCESS;
456 }
457
SetVolume(float left,float right)458 int32_t AudioRendererSink::SetVolume(float left, float right)
459 {
460 int32_t ret;
461 float volume;
462
463 if (audioRender_ == nullptr) {
464 AUDIO_ERR_LOG("AudioRendererSink::SetVolume failed audioRender_ null");
465 return ERR_INVALID_HANDLE;
466 }
467
468 leftVolume_ = left;
469 rightVolume_ = right;
470 if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
471 volume = rightVolume_;
472 } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
473 volume = leftVolume_;
474 } else {
475 volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
476 }
477
478 ret = audioRender_->volume.SetVolume(reinterpret_cast<AudioHandle>(audioRender_), volume);
479 if (ret) {
480 AUDIO_ERR_LOG("AudioRendererSink::Set volume failed!");
481 }
482
483 return ret;
484 }
485
GetVolume(float & left,float & right)486 int32_t AudioRendererSink::GetVolume(float &left, float &right)
487 {
488 left = leftVolume_;
489 right = rightVolume_;
490 return SUCCESS;
491 }
492
SetVoiceVolume(float volume)493 int32_t AudioRendererSink::SetVoiceVolume(float volume)
494 {
495 if (audioAdapter_ == nullptr) {
496 AUDIO_ERR_LOG("SetVoiceVolume failed, audioAdapter_ is null");
497 return ERR_INVALID_HANDLE;
498 }
499 AUDIO_DEBUG_LOG("SetVoiceVolume %{public}f", volume);
500 return audioAdapter_->SetVoiceVolume(audioAdapter_, volume);
501 }
502
GetLatency(uint32_t * latency)503 int32_t AudioRendererSink::GetLatency(uint32_t *latency)
504 {
505 if (audioRender_ == nullptr) {
506 AUDIO_ERR_LOG("AudioRendererSink: GetLatency failed audio render null");
507 return ERR_INVALID_HANDLE;
508 }
509
510 if (!latency) {
511 AUDIO_ERR_LOG("AudioRendererSink: GetLatency failed latency null");
512 return ERR_INVALID_PARAM;
513 }
514
515 uint32_t hdiLatency;
516 if (audioRender_->GetLatency(audioRender_, &hdiLatency) == 0) {
517 *latency = hdiLatency;
518 return SUCCESS;
519 } else {
520 return ERR_OPERATION_FAILED;
521 }
522 }
523
GetAudioCategory(AudioScene audioScene)524 static AudioCategory GetAudioCategory(AudioScene audioScene)
525 {
526 AudioCategory audioCategory;
527 switch (audioScene) {
528 case AUDIO_SCENE_DEFAULT:
529 audioCategory = AUDIO_IN_MEDIA;
530 break;
531 case AUDIO_SCENE_RINGING:
532 audioCategory = AUDIO_IN_RINGTONE;
533 break;
534 case AUDIO_SCENE_PHONE_CALL:
535 audioCategory = AUDIO_IN_CALL;
536 break;
537 case AUDIO_SCENE_PHONE_CHAT:
538 audioCategory = AUDIO_IN_COMMUNICATION;
539 break;
540 default:
541 audioCategory = AUDIO_IN_MEDIA;
542 break;
543 }
544 AUDIO_DEBUG_LOG("AudioRendererSink: Audio category returned is: %{public}d", audioCategory);
545
546 return audioCategory;
547 }
548
SetOutputPortPin(DeviceType outputDevice,AudioRouteNode & sink)549 static int32_t SetOutputPortPin(DeviceType outputDevice, AudioRouteNode &sink)
550 {
551 int32_t ret = SUCCESS;
552
553 switch (outputDevice) {
554 case DEVICE_TYPE_SPEAKER:
555 sink.ext.device.type = PIN_OUT_SPEAKER;
556 sink.ext.device.desc = "pin_out_speaker";
557 break;
558 case DEVICE_TYPE_WIRED_HEADSET:
559 sink.ext.device.type = PIN_OUT_HEADSET;
560 sink.ext.device.desc = "pin_out_headset";
561 break;
562 case DEVICE_TYPE_USB_HEADSET:
563 sink.ext.device.type = PIN_OUT_USB_EXT;
564 sink.ext.device.desc = "pin_out_usb_ext";
565 break;
566 case DEVICE_TYPE_BLUETOOTH_SCO:
567 sink.ext.device.type = PIN_OUT_BLUETOOTH_SCO;
568 sink.ext.device.desc = "pin_out_bluetooth_sco";
569 break;
570 default:
571 ret = ERR_NOT_SUPPORTED;
572 break;
573 }
574
575 return ret;
576 }
577
SetOutputRoute(DeviceType outputDevice)578 int32_t AudioRendererSink::SetOutputRoute(DeviceType outputDevice)
579 {
580 AudioPortPin outputPortPin = PIN_OUT_SPEAKER;
581 return SetOutputRoute(outputDevice, outputPortPin);
582 }
583
SetOutputRoute(DeviceType outputDevice,AudioPortPin & outputPortPin)584 int32_t AudioRendererSink::SetOutputRoute(DeviceType outputDevice, AudioPortPin &outputPortPin)
585 {
586 AudioRouteNode source = {};
587 AudioRouteNode sink = {};
588
589 int32_t ret = SetOutputPortPin(outputDevice, sink);
590 if (ret != SUCCESS) {
591 AUDIO_ERR_LOG("AudioRendererSink: SetOutputRoute FAILED: %{public}d", ret);
592 return ret;
593 }
594
595 outputPortPin = sink.ext.device.type;
596 AUDIO_INFO_LOG("AudioRendererSink: Output PIN is: 0x%{public}X", outputPortPin);
597 source.portId = 0;
598 source.role = AUDIO_PORT_SOURCE_ROLE;
599 source.type = AUDIO_PORT_MIX_TYPE;
600 source.ext.mix.moduleId = 0;
601 source.ext.mix.streamId = INTERNAL_OUTPUT_STREAM_ID;
602
603 sink.portId = static_cast<int32_t>(audioPort_.portId);
604 sink.role = AUDIO_PORT_SINK_ROLE;
605 sink.type = AUDIO_PORT_DEVICE_TYPE;
606 sink.ext.device.moduleId = 0;
607
608 AudioRoute route = {
609 .sourcesNum = 1,
610 .sources = &source,
611 .sinksNum = 1,
612 .sinks = &sink,
613 };
614
615 if (audioAdapter_ == nullptr) {
616 AUDIO_ERR_LOG("SetOutputRoute failed, audioAdapter_ is null");
617 return ERR_INVALID_PARAM;
618 }
619 ret = audioAdapter_->UpdateAudioRoute(audioAdapter_, &route, &routeHandle_);
620 if (ret != 0) {
621 AUDIO_ERR_LOG("UpdateAudioRoute failed");
622 return ERR_OPERATION_FAILED;
623 }
624
625 return SUCCESS;
626 }
627
SetAudioScene(AudioScene audioScene,DeviceType activeDevice)628 int32_t AudioRendererSink::SetAudioScene(AudioScene audioScene, DeviceType activeDevice)
629 {
630 AUDIO_INFO_LOG("AudioRendererSink::SetAudioScene scene: %{public}d, device: %{public}d",
631 audioScene, activeDevice);
632 CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene <= AUDIO_SCENE_PHONE_CHAT,
633 ERR_INVALID_PARAM, "invalid audioScene");
634 if (audioRender_ == nullptr) {
635 AUDIO_ERR_LOG("AudioRendererSink::SetAudioScene failed audio render handle is null!");
636 return ERR_INVALID_HANDLE;
637 }
638 if (openSpeaker_) {
639 AudioPortPin audioSceneOutPort = PIN_OUT_SPEAKER;
640 int32_t ret = SetOutputRoute(activeDevice, audioSceneOutPort);
641 if (ret < 0) {
642 AUDIO_ERR_LOG("AudioRendererSink: Update route FAILED: %{public}d", ret);
643 }
644
645 AUDIO_INFO_LOG("AudioRendererSink::OUTPUT port is %{public}d", audioSceneOutPort);
646 struct AudioSceneDescriptor scene;
647 scene.scene.id = GetAudioCategory(audioScene);
648 scene.desc.pins = audioSceneOutPort;
649 scene.desc.desc = nullptr;
650 if (audioRender_->scene.SelectScene == nullptr) {
651 AUDIO_ERR_LOG("AudioRendererSink: Select scene nullptr");
652 return ERR_OPERATION_FAILED;
653 }
654
655 ret = audioRender_->scene.SelectScene((AudioHandle)audioRender_, &scene);
656 if (ret < 0) {
657 AUDIO_ERR_LOG("AudioRendererSink: Select scene FAILED: %{public}d", ret);
658 return ERR_OPERATION_FAILED;
659 }
660 }
661
662 AUDIO_INFO_LOG("AudioRendererSink::Select audio scene SUCCESS: %{public}d", audioScene);
663 return SUCCESS;
664 }
665
GetTransactionId(uint64_t * transactionId)666 int32_t AudioRendererSink::GetTransactionId(uint64_t *transactionId)
667 {
668 AUDIO_INFO_LOG("AudioRendererSink::GetTransactionId in");
669
670 if (audioRender_ == nullptr) {
671 AUDIO_ERR_LOG("AudioRendererSink: GetTransactionId failed audio render null");
672 return ERR_INVALID_HANDLE;
673 }
674
675 if (!transactionId) {
676 AUDIO_ERR_LOG("AudioRendererSink: GetTransactionId failed transactionId null");
677 return ERR_INVALID_PARAM;
678 }
679
680 *transactionId = reinterpret_cast<uint64_t>(audioRender_);
681 return SUCCESS;
682 }
683
Stop(void)684 int32_t AudioRendererSink::Stop(void)
685 {
686 AUDIO_INFO_LOG("Stop.");
687
688 if (mKeepRunningLock != nullptr) {
689 AUDIO_INFO_LOG("AudioRendererSink call KeepRunningLock UnLock");
690 mKeepRunningLock->UnLock();
691 } else {
692 AUDIO_ERR_LOG("mKeepRunningLock is null, playback can not work well!");
693 }
694
695 int32_t ret;
696
697 if (audioRender_ == nullptr) {
698 AUDIO_ERR_LOG("AudioRendererSink::Stop failed audioRender_ null");
699 return ERR_INVALID_HANDLE;
700 }
701
702 if (started_) {
703 ret = audioRender_->control.Stop(reinterpret_cast<AudioHandle>(audioRender_));
704 if (!ret) {
705 started_ = false;
706 return SUCCESS;
707 } else {
708 AUDIO_ERR_LOG("AudioRendererSink::Stop failed!");
709 return ERR_OPERATION_FAILED;
710 }
711 }
712
713 return SUCCESS;
714 }
715
Pause(void)716 int32_t AudioRendererSink::Pause(void)
717 {
718 int32_t ret;
719
720 if (audioRender_ == nullptr) {
721 AUDIO_ERR_LOG("AudioRendererSink::Pause failed audioRender_ null");
722 return ERR_INVALID_HANDLE;
723 }
724
725 if (!started_) {
726 AUDIO_ERR_LOG("AudioRendererSink::Pause invalid state!");
727 return ERR_OPERATION_FAILED;
728 }
729
730 if (!paused_) {
731 ret = audioRender_->control.Pause(reinterpret_cast<AudioHandle>(audioRender_));
732 if (!ret) {
733 paused_ = true;
734 return SUCCESS;
735 } else {
736 AUDIO_ERR_LOG("AudioRendererSink::Pause failed!");
737 return ERR_OPERATION_FAILED;
738 }
739 }
740
741 return SUCCESS;
742 }
743
Resume(void)744 int32_t AudioRendererSink::Resume(void)
745 {
746 int32_t ret;
747
748 if (audioRender_ == nullptr) {
749 AUDIO_ERR_LOG("AudioRendererSink::Resume failed audioRender_ null");
750 return ERR_INVALID_HANDLE;
751 }
752
753 if (!started_) {
754 AUDIO_ERR_LOG("AudioRendererSink::Resume invalid state!");
755 return ERR_OPERATION_FAILED;
756 }
757
758 if (paused_) {
759 ret = audioRender_->control.Resume(reinterpret_cast<AudioHandle>(audioRender_));
760 if (!ret) {
761 paused_ = false;
762 return SUCCESS;
763 } else {
764 AUDIO_ERR_LOG("AudioRendererSink::Resume failed!");
765 return ERR_OPERATION_FAILED;
766 }
767 }
768
769 return SUCCESS;
770 }
771
Reset(void)772 int32_t AudioRendererSink::Reset(void)
773 {
774 int32_t ret;
775
776 if (started_ && audioRender_ != nullptr) {
777 ret = audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
778 if (!ret) {
779 return SUCCESS;
780 } else {
781 AUDIO_ERR_LOG("AudioRendererSink::Reset failed!");
782 return ERR_OPERATION_FAILED;
783 }
784 }
785
786 return ERR_OPERATION_FAILED;
787 }
788
Flush(void)789 int32_t AudioRendererSink::Flush(void)
790 {
791 int32_t ret;
792
793 if (started_ && audioRender_ != nullptr) {
794 ret = audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
795 if (!ret) {
796 return SUCCESS;
797 } else {
798 AUDIO_ERR_LOG("AudioRendererSink::Flush failed!");
799 return ERR_OPERATION_FAILED;
800 }
801 }
802
803 return ERR_OPERATION_FAILED;
804 }
805 } // namespace AudioStandard
806 } // namespace OHOS
807
808 #ifdef __cplusplus
809 extern "C" {
810 #endif
811
812 using namespace OHOS::AudioStandard;
813
814 AudioRendererSink *g_audioRendrSinkInstance = AudioRendererSink::GetInstance();
815
FillinAudioRenderSinkWapper(const char * deviceNetworkId,void ** wapper)816 int32_t FillinAudioRenderSinkWapper(const char *deviceNetworkId, void **wapper)
817 {
818 AudioRendererSink *instance = AudioRendererSink::GetInstance();
819 if (instance != nullptr) {
820 *wapper = static_cast<void *>(instance);
821 } else {
822 *wapper = nullptr;
823 }
824
825 return SUCCESS;
826 }
827
AudioRendererSinkInit(void * wapper,AudioSinkAttr * attr)828 int32_t AudioRendererSinkInit(void *wapper, AudioSinkAttr *attr)
829 {
830 (void)wapper;
831 int32_t ret;
832 if (g_audioRendrSinkInstance->rendererInited_)
833 return SUCCESS;
834
835 ret = g_audioRendrSinkInstance->Init(*attr);
836 return ret;
837 }
838
AudioRendererSinkDeInit(void * wapper)839 void AudioRendererSinkDeInit(void *wapper)
840 {
841 (void)wapper;
842 if (g_audioRendrSinkInstance->rendererInited_)
843 g_audioRendrSinkInstance->DeInit();
844 }
845
AudioRendererSinkStop(void * wapper)846 int32_t AudioRendererSinkStop(void *wapper)
847 {
848 (void)wapper;
849 int32_t ret;
850
851 if (!g_audioRendrSinkInstance->rendererInited_)
852 return SUCCESS;
853
854 ret = g_audioRendrSinkInstance->Stop();
855 return ret;
856 }
857
AudioRendererSinkStart(void * wapper)858 int32_t AudioRendererSinkStart(void *wapper)
859 {
860 (void)wapper;
861 int32_t ret;
862
863 if (!g_audioRendrSinkInstance->rendererInited_) {
864 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
865 return ERR_NOT_STARTED;
866 }
867
868 ret = g_audioRendrSinkInstance->Start();
869 return ret;
870 }
871
AudioRendererSinkPause(void * wapper)872 int32_t AudioRendererSinkPause(void *wapper)
873 {
874 (void)wapper;
875 if (!g_audioRendrSinkInstance->rendererInited_) {
876 AUDIO_ERR_LOG("Renderer pause failed");
877 return ERR_NOT_STARTED;
878 }
879
880 return g_audioRendrSinkInstance->Pause();
881 }
882
AudioRendererSinkResume(void * wapper)883 int32_t AudioRendererSinkResume(void *wapper)
884 {
885 (void)wapper;
886 if (!g_audioRendrSinkInstance->rendererInited_) {
887 AUDIO_ERR_LOG("Renderer resume failed");
888 return ERR_NOT_STARTED;
889 }
890
891 return g_audioRendrSinkInstance->Resume();
892 }
893
AudioRendererRenderFrame(void * wapper,char & data,uint64_t len,uint64_t & writeLen)894 int32_t AudioRendererRenderFrame(void *wapper, char &data, uint64_t len, uint64_t &writeLen)
895 {
896 (void)wapper;
897 int32_t ret;
898
899 if (!g_audioRendrSinkInstance->rendererInited_) {
900 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
901 return ERR_NOT_STARTED;
902 }
903
904 ret = g_audioRendrSinkInstance->RenderFrame(data, len, writeLen);
905 return ret;
906 }
907
AudioRendererSinkSetVolume(void * wapper,float left,float right)908 int32_t AudioRendererSinkSetVolume(void *wapper, float left, float right)
909 {
910 (void)wapper;
911 int32_t ret;
912
913 if (!g_audioRendrSinkInstance->rendererInited_) {
914 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
915 return ERR_NOT_STARTED;
916 }
917
918 ret = g_audioRendrSinkInstance->SetVolume(left, right);
919 return ret;
920 }
921
AudioRendererSinkGetLatency(void * wapper,uint32_t * latency)922 int32_t AudioRendererSinkGetLatency(void *wapper, uint32_t *latency)
923 {
924 (void)wapper;
925 int32_t ret;
926
927 if (!g_audioRendrSinkInstance->rendererInited_) {
928 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
929 return ERR_NOT_STARTED;
930 }
931
932 if (!latency) {
933 AUDIO_ERR_LOG("AudioRendererSinkGetLatency failed latency null");
934 return ERR_INVALID_PARAM;
935 }
936
937 ret = g_audioRendrSinkInstance->GetLatency(latency);
938 return ret;
939 }
940
AudioRendererSinkGetTransactionId(uint64_t * transactionId)941 int32_t AudioRendererSinkGetTransactionId(uint64_t *transactionId)
942 {
943 if (!g_audioRendrSinkInstance->rendererInited_) {
944 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first");
945 return ERR_NOT_STARTED;
946 }
947
948 if (!transactionId) {
949 AUDIO_ERR_LOG("AudioRendererSinkGetTransactionId failed transaction id null");
950 return ERR_INVALID_PARAM;
951 }
952
953 return g_audioRendrSinkInstance->GetTransactionId(transactionId);
954 }
955 #ifdef __cplusplus
956 }
957 #endif
958