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