1 /*
2 * Copyright (c) 2025 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 #ifndef LOG_TAG
17 #define LOG_TAG "AudioRenderSink"
18 #endif
19
20 #include "sink/audio_render_sink.h"
21 #include <thread>
22 #include <climits>
23 #include "parameters.h"
24 #include "audio_hdi_log.h"
25 #include "audio_errors.h"
26 #include "audio_dump_pcm.h"
27 #include "volume_tools.h"
28 #include "media_monitor_manager.h"
29 #include "audio_enhance_chain_manager.h"
30 #include "common/hdi_adapter_info.h"
31 #include "manager/hdi_adapter_manager.h"
32 #include "manager/hdi_monitor.h"
33 #include "adapter/i_device_manager.h"
34
35 namespace OHOS {
36 namespace AudioStandard {
37 namespace {
38 const int64_t RENDER_FRAME_LIMIT = 50; // 50ms
39 const int64_t RENDER_FRAME_REPORT_LIMIT = 100000000; // 100ms
40 }
AudioRenderSink(const uint32_t renderId,const std::string & halName)41 AudioRenderSink::AudioRenderSink(const uint32_t renderId, const std::string &halName)
42 : renderId_(renderId), halName_(halName)
43 {
44 if (halName_ == HDI_ID_INFO_DIRECT || halName_ == HDI_ID_INFO_VOIP) {
45 sinkType_ = ADAPTER_TYPE_DIRECT;
46 }
47 }
48
~AudioRenderSink()49 AudioRenderSink::~AudioRenderSink()
50 {
51 AUDIO_WARNING_LOG("in");
52 AUDIO_INFO_LOG("[%{public}s] volumeDataCount: %{public}" PRId64, logUtilsTag_.c_str(), volumeDataCount_);
53 #ifdef FEATURE_POWER_MANAGER
54 if (runningLock_ != nullptr) {
55 AUDIO_INFO_LOG("running lock unlock");
56 runningLock_->UnLock();
57 } else {
58 AUDIO_WARNING_LOG("running lock is null, playback can not work well");
59 }
60 #endif
61 AudioPerformanceMonitor::GetInstance().DeleteOvertimeMonitor(sinkType_);
62 }
63
Init(const IAudioSinkAttr & attr)64 int32_t AudioRenderSink::Init(const IAudioSinkAttr &attr)
65 {
66 std::lock_guard<std::mutex> lock(sinkMutex_);
67 attr_ = attr;
68 adapterNameCase_ = attr_.adapterName;
69 AUDIO_INFO_LOG("adapterNameCase_: %{public}s", adapterNameCase_.c_str());
70 openSpeaker_ = attr_.openMicSpeaker;
71
72 Trace trace("AudioRenderSink::Init " + adapterNameCase_);
73 int32_t ret = InitRender();
74 CHECK_AND_RETURN_RET(ret == SUCCESS, ret);
75
76 HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
77 std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
78 CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
79
80 sinkInited_ = true;
81 return SUCCESS;
82 }
83
DeInit(void)84 void AudioRenderSink::DeInit(void)
85 {
86 std::lock_guard<std::mutex> lock(sinkMutex_);
87 sinkInited_ = false;
88 started_ = false;
89
90 AUDIO_INFO_LOG("destroy render, hdiRenderId: %{public}u", hdiRenderId_);
91 HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
92 std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
93 CHECK_AND_RETURN(deviceManager != nullptr);
94 renderInited_ = false;
95 deviceManager->DestroyRender(adapterNameCase_, hdiRenderId_);
96 audioRender_ = nullptr;
97 }
98
IsInited(void)99 bool AudioRenderSink::IsInited(void)
100 {
101 return sinkInited_;
102 }
103
Start(void)104 int32_t AudioRenderSink::Start(void)
105 {
106 std::lock_guard<std::mutex> lock(sinkMutex_);
107 AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
108 Trace trace("AudioRenderSink::Start");
109 #ifdef FEATURE_POWER_MANAGER
110 AudioXCollie audioXCollie("AudioRenderSink::CreateRunningLock", TIMEOUT_SECONDS_10,
111 nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
112 if (runningLock_ == nullptr) {
113 WatchTimeout guard("create AudioRunningLock start");
114 runningLock_ = std::make_shared<AudioRunningLock>(std::string(RUNNING_LOCK_NAME_BASE) + halName_);
115 guard.CheckCurrTimeout();
116 }
117 if (runningLock_ != nullptr) {
118 runningLock_->Lock(RUNNING_LOCK_TIMEOUTMS_LASTING);
119 } else {
120 AUDIO_ERR_LOG("running lock is null, playback can not work well");
121 }
122 audioXCollie.CancelXCollieTimer();
123 #endif
124 dumpFileName_ = halName_ + "_sink_" + GetTime() + "_" + std::to_string(attr_.sampleRate) + "_" +
125 std::to_string(attr_.channel) + "_" + std::to_string(attr_.format) + ".pcm";
126 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpFile_);
127 logUtilsTag_ = "AudioSink" + halName_;
128
129 InitLatencyMeasurement();
130 if (started_) {
131 return SUCCESS;
132 }
133 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
134 int32_t ret = audioRender_->Start(audioRender_);
135 if (ret != SUCCESS) {
136 HdiMonitor::ReportHdiException(HdiType::LOCAL, ErrorCase::CALL_HDI_FAILED, ret,
137 "local start failed, halName_:" + halName_);
138 }
139 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "start fail");
140 UpdateSinkState(true);
141 AudioPerformanceMonitor::GetInstance().RecordTimeStamp(sinkType_, INIT_LASTWRITTEN_TIME);
142 started_ = true;
143 isDataLinkConnected_ = false;
144 return SUCCESS;
145 }
146
Stop(void)147 int32_t AudioRenderSink::Stop(void)
148 {
149 std::lock_guard<std::mutex> lock(sinkMutex_);
150 AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
151 Trace trace("AudioRenderSink::Stop");
152 #ifdef FEATURE_POWER_MANAGER
153 if (runningLock_ != nullptr) {
154 std::thread runningLockThread([this] {
155 runningLock_->UnLock();
156 });
157 runningLockThread.join();
158 }
159 #endif
160
161 DeInitLatencyMeasurement();
162 if (!started_) {
163 return SUCCESS;
164 }
165 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
166 if (halName_ == "primary") {
167 const char keyValueList[] = "primary=stop";
168 if (audioRender_->SetExtraParams(audioRender_, keyValueList) == 0) {
169 AUDIO_INFO_LOG("set primary stream stop info to hal");
170 }
171 }
172 int32_t ret = audioRender_->Stop(audioRender_);
173 UpdateSinkState(false);
174 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "stop fail");
175 started_ = false;
176
177 DumpFileUtil::CloseDumpFile(&dumpFile_);
178 return SUCCESS;
179 }
180
Resume(void)181 int32_t AudioRenderSink::Resume(void)
182 {
183 std::lock_guard<std::mutex> lock(sinkMutex_);
184 AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
185 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
186 CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
187
188 if (!paused_) {
189 return SUCCESS;
190 }
191 int32_t ret = audioRender_->Resume(audioRender_);
192 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "resume fail");
193 AudioPerformanceMonitor::GetInstance().RecordTimeStamp(sinkType_, INIT_LASTWRITTEN_TIME);
194 paused_ = false;
195 return SUCCESS;
196 }
197
Pause(void)198 int32_t AudioRenderSink::Pause(void)
199 {
200 std::lock_guard<std::mutex> lock(sinkMutex_);
201 AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
202 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
203 CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
204
205 if (paused_) {
206 return SUCCESS;
207 }
208 int32_t ret = audioRender_->Pause(audioRender_);
209 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "pause fail");
210 paused_ = true;
211 return SUCCESS;
212 }
213
Flush(void)214 int32_t AudioRenderSink::Flush(void)
215 {
216 AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
217 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
218 CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
219
220 int32_t ret = audioRender_->Flush(audioRender_);
221 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "flush fail");
222 return SUCCESS;
223 }
224
Reset(void)225 int32_t AudioRenderSink::Reset(void)
226 {
227 AUDIO_INFO_LOG("halName: %{public}s", halName_.c_str());
228 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
229 CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
230
231 int32_t ret = audioRender_->Flush(audioRender_);
232 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "reset fail");
233 return SUCCESS;
234 }
235
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)236 int32_t AudioRenderSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
237 {
238 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
239 if (!started_) {
240 AUDIO_WARNING_LOG("not start, invalid state");
241 }
242 if (audioMonoState_) {
243 AdjustStereoToMono(&data, len);
244 }
245 if (audioBalanceState_) {
246 AdjustAudioBalance(&data, len);
247 }
248 CheckUpdateState(&data, len);
249 if (switchDeviceMute_ || deviceConnectedFlag_) {
250 Trace trace("AudioRenderSink::RenderFrame::renderEmpty");
251 if (memset_s(reinterpret_cast<void *>(&data), static_cast<size_t>(len), 0, static_cast<size_t>(len)) != EOK) {
252 AUDIO_WARNING_LOG("call memset_s fail");
253 }
254 }
255 CheckLatencySignal(reinterpret_cast<uint8_t *>(&data), len);
256
257 BufferDesc buffer = { reinterpret_cast<uint8_t *>(&data), len, len };
258 AudioStreamInfo streamInfo(static_cast<AudioSamplingRate>(attr_.sampleRate), AudioEncodingType::ENCODING_PCM,
259 static_cast<AudioSampleFormat>(attr_.format), static_cast<AudioChannel>(attr_.channel));
260 VolumeTools::DfxOperation(buffer, streamInfo, logUtilsTag_, volumeDataCount_);
261 if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
262 DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(&data), len);
263 AudioCacheMgr::GetInstance().CacheData(dumpFileName_, static_cast<void *>(&data), len);
264 }
265 Trace trace("AudioRenderSink::RenderFrame");
266 int64_t stamp = ClockTime::GetCurNano();
267 int32_t ret = audioRender_->RenderFrame(audioRender_, reinterpret_cast<int8_t *>(&data), static_cast<uint32_t>(len),
268 &writeLen);
269 stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
270 AudioPerformanceMonitor::GetInstance().RecordTimeStamp(sinkType_, ClockTime::GetCurNano());
271 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_WRITE_FAILED, "fail, ret: %{public}x", ret);
272 if (stamp >= RENDER_FRAME_LIMIT) {
273 AUDIO_WARNING_LOG("len: [%{public}" PRIu64 "], cost: [%{public}" PRId64 "]ms", len, stamp);
274 }
275 #ifdef FEATURE_POWER_MANAGER
276 if (runningLock_) {
277 runningLock_->UpdateAppsUidToPowerMgr();
278 }
279 #endif
280 if (stamp > RENDER_FRAME_REPORT_LIMIT) {
281 HdiMonitor::ReportHdiException(HdiType::LOCAL, ErrorCase::CALL_HDI_TIMEOUT,
282 static_cast<int32_t>(stamp), "call RenderFrame too long, " + halName_);
283 }
284
285 return SUCCESS;
286 }
287
GetVolumeDataCount()288 int64_t AudioRenderSink::GetVolumeDataCount()
289 {
290 return volumeDataCount_;
291 }
292
SuspendRenderSink(void)293 int32_t AudioRenderSink::SuspendRenderSink(void)
294 {
295 return SUCCESS;
296 }
297
RestoreRenderSink(void)298 int32_t AudioRenderSink::RestoreRenderSink(void)
299 {
300 return SUCCESS;
301 }
302
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)303 void AudioRenderSink::SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value)
304 {
305 AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, value: %{public}s", key, condition.c_str(), value.c_str());
306 CHECK_AND_RETURN_LOG(audioRender_ != nullptr, "render is nullptr");
307 int32_t ret = audioRender_->SetExtraParams(audioRender_, value.c_str());
308 if (ret != SUCCESS) {
309 AUDIO_WARNING_LOG("set parameter fail, error code: %{public}d", ret);
310 }
311 }
312
GetAudioParameter(const AudioParamKey key,const std::string & condition)313 std::string AudioRenderSink::GetAudioParameter(const AudioParamKey key, const std::string &condition)
314 {
315 std::lock_guard<std::mutex> lock(sinkMutex_);
316 AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, halName: %{public}s", key, condition.c_str(),
317 halName_.c_str());
318 if (condition.starts_with("get_usb_info#C") && halName_ == HDI_ID_INFO_USB) {
319 // init adapter to get parameter before load sink module (need fix)
320 adapterNameCase_ = "usb";
321 HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
322 std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
323 CHECK_AND_RETURN_RET_LOG(deviceManager != nullptr, "", "deviceManager is nullptr");
324 return deviceManager->GetAudioParameter(adapterNameCase_, key, condition);
325 }
326 if (key == AudioParamKey::GET_DP_DEVICE_INFO && halName_ == HDI_ID_INFO_DP) {
327 // init adapter and render to get parameter before load sink module (need fix)
328 return GetDPDeviceInfo(condition);
329 }
330 return "";
331 }
332
SetVolume(float left,float right)333 int32_t AudioRenderSink::SetVolume(float left, float right)
334 {
335 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
336
337 leftVolume_ = left;
338 rightVolume_ = right;
339 CHECK_AND_RETURN_RET_LOG(!(halName_ == "voip" && switchDeviceMute_ && (abs(left) > FLOAT_EPS ||
340 abs(right) > FLOAT_EPS)), ERR_ILLEGAL_STATE, "mute for switch device at voip scene, not support set volume");
341 float volume;
342 if ((abs(leftVolume_) < FLOAT_EPS) && (abs(rightVolume_) > FLOAT_EPS)) {
343 volume = rightVolume_;
344 } else if ((abs(leftVolume_) > FLOAT_EPS) && (abs(rightVolume_) < FLOAT_EPS)) {
345 volume = leftVolume_;
346 } else {
347 volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
348 }
349
350 int32_t ret = audioRender_->SetVolume(audioRender_, volume);
351 if (ret != SUCCESS) {
352 AUDIO_WARNING_LOG("set volume fail");
353 }
354
355 return ret;
356 }
357
GetVolume(float & left,float & right)358 int32_t AudioRenderSink::GetVolume(float &left, float &right)
359 {
360 left = leftVolume_;
361 right = rightVolume_;
362 return SUCCESS;
363 }
364
GetLatency(uint32_t & latency)365 int32_t AudioRenderSink::GetLatency(uint32_t &latency)
366 {
367 Trace trace("AudioRenderSink::GetLatency");
368 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
369
370 uint32_t hdiLatency;
371 int32_t ret = audioRender_->GetLatency(audioRender_, &hdiLatency);
372 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get latency fail");
373 latency = hdiLatency;
374 return SUCCESS;
375 }
376
GetTransactionId(uint64_t & transactionId)377 int32_t AudioRenderSink::GetTransactionId(uint64_t &transactionId)
378 {
379 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
380 transactionId = reinterpret_cast<uint64_t>(audioRender_);
381 return SUCCESS;
382 }
383
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)384 int32_t AudioRenderSink::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
385 {
386 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
387
388 struct AudioTimeStamp stamp = {};
389 int32_t ret = audioRender_->GetRenderPosition(audioRender_, &frames, &stamp);
390 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get render position fail, ret: %{public}d", ret);
391 int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it
392 CHECK_AND_RETURN_RET_LOG(stamp.tvSec >= 0 && stamp.tvSec <= maxSec && stamp.tvNSec >= 0 &&
393 stamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED,
394 "get invalid time, second: %{public}" PRId64 ", nanosecond: %{public}" PRId64, stamp.tvSec, stamp.tvNSec);
395 timeSec = stamp.tvSec;
396 timeNanoSec = stamp.tvNSec;
397 return ret;
398 }
399
GetMaxAmplitude(void)400 float AudioRenderSink::GetMaxAmplitude(void)
401 {
402 lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano();
403 startUpdate_ = true;
404 return maxAmplitude_;
405 }
406
SetAudioMonoState(bool audioMono)407 void AudioRenderSink::SetAudioMonoState(bool audioMono)
408 {
409 audioMonoState_ = audioMono;
410 }
411
SetAudioBalanceValue(float audioBalance)412 void AudioRenderSink::SetAudioBalanceValue(float audioBalance)
413 {
414 // reset the balance coefficient value firstly
415 leftBalanceCoef_ = 1.0f;
416 rightBalanceCoef_ = 1.0f;
417
418 if (std::abs(audioBalance - 0.0f) <= std::numeric_limits<float>::epsilon()) {
419 // audioBalance is equal to 0.0f
420 audioBalanceState_ = false;
421 } else {
422 // audioBalance is not equal to 0.0f
423 audioBalanceState_ = true;
424 // calculate the balance coefficient
425 if (audioBalance > 0.0f) {
426 leftBalanceCoef_ -= audioBalance;
427 } else if (audioBalance < 0.0f) {
428 rightBalanceCoef_ += audioBalance;
429 }
430 }
431 }
432
SetSinkMuteForSwitchDevice(bool mute)433 int32_t AudioRenderSink::SetSinkMuteForSwitchDevice(bool mute)
434 {
435 std::lock_guard<std::mutex> lock(switchDeviceMutex_);
436 AUDIO_INFO_LOG("set %{public}s mute %{public}d", halName_.c_str(), mute);
437 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
438
439 if (mute) {
440 muteCount_++;
441 if (switchDeviceMute_) {
442 AUDIO_INFO_LOG("%{public}s already muted", halName_.c_str());
443 return SUCCESS;
444 }
445 switchDeviceMute_ = true;
446 if (halName_ == HDI_ID_INFO_VOIP) {
447 audioRender_->SetVolume(audioRender_, 0.0f);
448 }
449 } else {
450 muteCount_--;
451 if (muteCount_ > 0) {
452 AUDIO_WARNING_LOG("%{public}s not all unmuted", halName_.c_str());
453 return SUCCESS;
454 }
455 switchDeviceMute_ = false;
456 muteCount_ = 0;
457 if (halName_ == HDI_ID_INFO_VOIP) {
458 SetVolume(leftVolume_, rightVolume_);
459 }
460 }
461
462 return SUCCESS;
463 }
464
SetDeviceConnectedFlag(bool flag)465 int32_t AudioRenderSink::SetDeviceConnectedFlag(bool flag)
466 {
467 AUDIO_INFO_LOG("flag %{public}d", flag);
468 deviceConnectedFlag_ = flag;
469 return SUCCESS;
470 }
471
SetAudioScene(AudioScene audioScene,bool scoExcludeFlag)472 int32_t AudioRenderSink::SetAudioScene(AudioScene audioScene, bool scoExcludeFlag)
473 {
474 CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene < AUDIO_SCENE_MAX, ERR_INVALID_PARAM,
475 "invalid scene");
476 if (!openSpeaker_) {
477 return SUCCESS;
478 }
479
480 if (audioScene != currentAudioScene_ && !scoExcludeFlag) {
481 struct AudioSceneDescriptor sceneDesc;
482 InitSceneDesc(sceneDesc, audioScene);
483
484 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
485 int32_t ret = audioRender_->SelectScene(audioRender_, &sceneDesc);
486 CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_OPERATION_FAILED, "select scene fail, ret: %{public}d", ret);
487 }
488 bool isRingingToDefaultScene = false;
489 if (audioScene != currentAudioScene_) {
490 if (audioScene == AUDIO_SCENE_PHONE_CALL || audioScene == AUDIO_SCENE_PHONE_CHAT) {
491 forceSetRouteFlag_ = true;
492 }
493 if (audioScene == AUDIO_SCENE_DEFAULT &&
494 (currentAudioScene_ == AUDIO_SCENE_RINGING || currentAudioScene_ == AUDIO_SCENE_VOICE_RINGING)) {
495 isRingingToDefaultScene = true;
496 }
497 currentAudioScene_ = audioScene;
498 }
499
500 HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
501 std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
502 CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
503 deviceManager->SetAudioScene(currentAudioScene_);
504
505 if (isRingingToDefaultScene) {
506 AUDIO_INFO_LOG("ringing scene to default scene");
507 return SUCCESS;
508 }
509 return SUCCESS;
510 }
511
GetAudioScene(void)512 int32_t AudioRenderSink::GetAudioScene(void)
513 {
514 return currentAudioScene_;
515 }
516
UpdateActiveDevice(std::vector<DeviceType> & outputDevices)517 int32_t AudioRenderSink::UpdateActiveDevice(std::vector<DeviceType> &outputDevices)
518 {
519 CHECK_AND_RETURN_RET_LOG(!outputDevices.empty() && outputDevices.size() <= AUDIO_CONCURRENT_ACTIVE_DEVICES_LIMIT,
520 ERR_INVALID_PARAM, "invalid device");
521 AUDIO_INFO_LOG("device: %{public}d, currentActiveDevice: %{public}d", outputDevices[0], currentActiveDevice_);
522 if (currentActiveDevice_ == outputDevices[0] && outputDevices.size() ==
523 static_cast<uint32_t>(currentDevicesSize_) && !forceSetRouteFlag_) {
524 AUDIO_INFO_LOG("output device not change, device: %{public}d", outputDevices[0]);
525 return SUCCESS;
526 }
527 forceSetRouteFlag_ = false;
528 currentActiveDevice_ = outputDevices[0];
529 currentDevicesSize_ = static_cast<int32_t>(outputDevices.size());
530 SetAudioRouteInfoForEnhanceChain();
531 return DoSetOutputRoute(outputDevices);
532 }
533
RegistCallback(uint32_t type,IAudioSinkCallback * callback)534 void AudioRenderSink::RegistCallback(uint32_t type, IAudioSinkCallback *callback)
535 {
536 std::lock_guard<std::mutex> lock(sinkMutex_);
537 callback_.RegistCallback(type, callback);
538 AUDIO_INFO_LOG("regist succ");
539 }
540
ResetActiveDeviceForDisconnect(DeviceType device)541 void AudioRenderSink::ResetActiveDeviceForDisconnect(DeviceType device)
542 {
543 if (currentActiveDevice_ == device) {
544 currentActiveDevice_ = DEVICE_TYPE_NONE;
545 }
546 }
547
SetPaPower(int32_t flag)548 int32_t AudioRenderSink::SetPaPower(int32_t flag)
549 {
550 Trace trace("AudioRenderSink::SetPaPower flag: " + std::to_string(flag));
551 std::string param;
552
553 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr");
554 AUDIO_INFO_LOG("flag: %{public}d, paStatus: %{public}d", flag, paStatus_);
555 if (flag == 0 && paStatus_ == 1) {
556 param = "zero_volume=true;routing=0";
557 AUDIO_INFO_LOG("param: %{public}s", param.c_str());
558 int32_t ret = audioRender_->SetExtraParams(audioRender_, param.c_str());
559 if (ret == SUCCESS) {
560 paStatus_ = 0;
561 WriteSmartPAStatusSysEvent(paStatus_);
562 }
563 return ret;
564 } else if (flag == 1 && paStatus_ == 0) {
565 param = "zero_volume=true;routing=" + GetRouting();
566 AUDIO_INFO_LOG("param: %{public}s", param.c_str());
567 int32_t ret = audioRender_->SetExtraParams(audioRender_, param.c_str());
568 param = "zero_volume=false";
569 ret += audioRender_->SetExtraParams(audioRender_, param.c_str());
570 if (ret == SUCCESS) {
571 paStatus_ = 1;
572 WriteSmartPAStatusSysEvent(paStatus_);
573 }
574 return ret;
575 } else if ((flag == 0 && paStatus_ == 0) || (flag == 1 && paStatus_ == 1)) {
576 return SUCCESS;
577 }
578
579 AUDIO_WARNING_LOG("invalid flag");
580 return ERR_INVALID_PARAM;
581 }
582
SetPriPaPower(void)583 int32_t AudioRenderSink::SetPriPaPower(void)
584 {
585 time_t currentTime = time(nullptr);
586 double diff = difftime(currentTime, startTime_);
587 if (diff > INTERVAL) {
588 CHECK_AND_RETURN_RET(audioRender_ != nullptr, ERR_INVALID_HANDLE);
589 int32_t ret = audioRender_->SetExtraParams(audioRender_, "primary=start");
590 if (ret == SUCCESS) {
591 AUDIO_INFO_LOG("set primary stream start info to hal");
592 }
593 time(&startTime_);
594 return ret;
595 }
596 return ERR_OPERATION_FAILED;
597 }
598
UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],const size_t size)599 int32_t AudioRenderSink::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size)
600 {
601 #ifdef FEATURE_POWER_MANAGER
602 CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr");
603 runningLock_->UpdateAppsUid(appsUid, appsUid + size);
604 #endif
605 return SUCCESS;
606 }
607
UpdateAppsUid(const std::vector<int32_t> & appsUid)608 int32_t AudioRenderSink::UpdateAppsUid(const std::vector<int32_t> &appsUid)
609 {
610 #ifdef FEATURE_POWER_MANAGER
611 CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr");
612 runningLock_->UpdateAppsUid(appsUid.cbegin(), appsUid.cend());
613 runningLock_->UpdateAppsUidToPowerMgr();
614 #endif
615 return SUCCESS;
616 }
617
SetAddress(const std::string & address)618 void AudioRenderSink::SetAddress(const std::string &address)
619 {
620 address_ = address;
621 }
622
DumpInfo(std::string & dumpString)623 void AudioRenderSink::DumpInfo(std::string &dumpString)
624 {
625 dumpString += "type: PrimarySink\tstarted: " + std::string(started_ ? "true" : "false") + "\thalName: " + halName_ +
626 "\tcurrentActiveDevice: " + std::to_string(currentActiveDevice_) + "\n";
627 }
628
PcmFormatToBit(AudioSampleFormat format)629 uint32_t AudioRenderSink::PcmFormatToBit(AudioSampleFormat format)
630 {
631 AudioFormat hdiFormat = ConvertToHdiFormat(format);
632 switch (hdiFormat) {
633 case AUDIO_FORMAT_TYPE_PCM_8_BIT:
634 return PCM_8_BIT;
635 case AUDIO_FORMAT_TYPE_PCM_16_BIT:
636 return PCM_16_BIT;
637 case AUDIO_FORMAT_TYPE_PCM_24_BIT:
638 return PCM_24_BIT;
639 case AUDIO_FORMAT_TYPE_PCM_32_BIT:
640 return PCM_32_BIT;
641 default:
642 AUDIO_DEBUG_LOG("unknown format type, set it to default");
643 return PCM_24_BIT;
644 }
645 }
646
ConvertToHdiFormat(AudioSampleFormat format)647 AudioFormat AudioRenderSink::ConvertToHdiFormat(AudioSampleFormat format)
648 {
649 AudioFormat hdiFormat;
650 switch (format) {
651 case SAMPLE_U8:
652 hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
653 break;
654 case SAMPLE_S16LE:
655 hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
656 break;
657 case SAMPLE_S24LE:
658 hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
659 break;
660 case SAMPLE_S32LE:
661 hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
662 break;
663 default:
664 hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
665 break;
666 }
667 return hdiFormat;
668 }
669
ConvertByteToAudioFormat(int32_t format)670 int32_t AudioRenderSink::ConvertByteToAudioFormat(int32_t format)
671 {
672 int32_t audioSampleFormat = 0;
673 switch (format) {
674 case FORMAT_1_BYTE:
675 audioSampleFormat = SAMPLE_U8;
676 break;
677 case FORMAT_2_BYTE:
678 audioSampleFormat = SAMPLE_S16LE;
679 break;
680 case FORMAT_3_BYTE:
681 audioSampleFormat = SAMPLE_S24LE;
682 break;
683 case FORMAT_4_BYTE:
684 audioSampleFormat = SAMPLE_S32LE;
685 break;
686 default:
687 audioSampleFormat = SAMPLE_S16LE;
688 break;
689 }
690 return audioSampleFormat;
691 }
692
ParseAudioFormatToStr(int32_t format)693 std::string AudioRenderSink::ParseAudioFormatToStr(int32_t format)
694 {
695 switch (format) {
696 case FORMAT_1_BYTE:
697 return "u8";
698 case FORMAT_2_BYTE:
699 return "s16";
700 case FORMAT_3_BYTE:
701 return "s24";
702 case FORMAT_4_BYTE:
703 return "s32";
704 default:
705 return "s16";
706 }
707 return "";
708 }
709
ParseAudioFormat(const std::string & format)710 AudioSampleFormat AudioRenderSink::ParseAudioFormat(const std::string &format)
711 {
712 if (format == "AUDIO_FORMAT_PCM_16_BIT") {
713 return SAMPLE_S16LE;
714 } else if (format == "AUDIO_FORMAT_PCM_24_BIT" || format == "AUDIO_FORMAT_PCM_24_BIT_PACKED") {
715 return SAMPLE_S24LE;
716 } else if (format == "AUDIO_FORMAT_PCM_32_BIT") {
717 return SAMPLE_S32LE;
718 } else {
719 return SAMPLE_S16LE;
720 }
721 }
722
GetAudioCategory(AudioScene audioScene)723 AudioCategory AudioRenderSink::GetAudioCategory(AudioScene audioScene)
724 {
725 AudioCategory audioCategory;
726 switch (audioScene) {
727 case AUDIO_SCENE_DEFAULT:
728 audioCategory = AUDIO_IN_MEDIA;
729 break;
730 case AUDIO_SCENE_RINGING:
731 case AUDIO_SCENE_VOICE_RINGING:
732 audioCategory = AUDIO_IN_RINGTONE;
733 break;
734 case AUDIO_SCENE_PHONE_CALL:
735 audioCategory = AUDIO_IN_CALL;
736 break;
737 case AUDIO_SCENE_PHONE_CHAT:
738 audioCategory = AUDIO_IN_COMMUNICATION;
739 break;
740 default:
741 audioCategory = AUDIO_IN_MEDIA;
742 break;
743 }
744 AUDIO_DEBUG_LOG("audioCategory: %{public}d", audioCategory);
745
746 return audioCategory;
747 }
748
GetAudioPortPin(void) const749 AudioPortPin AudioRenderSink::GetAudioPortPin(void) const noexcept
750 {
751 switch (attr_.deviceType) {
752 case DEVICE_TYPE_EARPIECE:
753 return PIN_OUT_EARPIECE;
754 case DEVICE_TYPE_SPEAKER:
755 return PIN_OUT_SPEAKER;
756 case DEVICE_TYPE_WIRED_HEADSET:
757 return PIN_OUT_HEADSET;
758 case DEVICE_TYPE_WIRED_HEADPHONES:
759 return PIN_OUT_HEADPHONE;
760 case DEVICE_TYPE_BLUETOOTH_SCO:
761 return PIN_OUT_BLUETOOTH_SCO;
762 case DEVICE_TYPE_USB_HEADSET:
763 return PIN_OUT_USB_EXT;
764 case DEVICE_TYPE_HDMI:
765 return PIN_OUT_HDMI;
766 case DEVICE_TYPE_NONE:
767 return PIN_NONE;
768 default:
769 return PIN_OUT_SPEAKER;
770 }
771 }
772
GetUniqueId(void) const773 uint32_t AudioRenderSink::GetUniqueId(void) const
774 {
775 if (halName_ == HDI_ID_INFO_USB) {
776 return GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_USB);
777 } else if (halName_ == HDI_ID_INFO_DP) {
778 return GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_DP);
779 } else if (halName_ == HDI_ID_INFO_VOIP) {
780 return GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_VOIP);
781 } else if (halName_ == HDI_ID_INFO_DIRECT) {
782 return GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_DIRECT);
783 }
784 return GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_PRIMARY);
785 }
786
InitAudioSampleAttr(struct AudioSampleAttributes & param)787 void AudioRenderSink::InitAudioSampleAttr(struct AudioSampleAttributes ¶m)
788 {
789 param.channelCount = AUDIO_CHANNELCOUNT;
790 param.sampleRate = AUDIO_SAMPLE_RATE_48K;
791 param.interleaved = true;
792 param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_PRIMARY));
793 param.type = AUDIO_IN_MEDIA;
794 param.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
795 param.isBigEndian = false;
796 param.isSignedData = true;
797 param.stopThreshold = INT_MAX;
798 param.silenceThreshold = 0;
799
800 param.sampleRate = attr_.sampleRate;
801 param.channelCount = attr_.channel;
802 if (param.channelCount == MONO) {
803 param.channelLayout = CH_LAYOUT_MONO;
804 } else if (param.channelCount == STEREO) {
805 param.channelLayout = CH_LAYOUT_STEREO;
806 }
807 if (halName_ == HDI_ID_INFO_DP) {
808 param.type = AUDIO_DP;
809 } else if (halName_ == HDI_ID_INFO_DIRECT) {
810 param.type = AUDIO_DIRECT;
811 param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_DIRECT));
812 } else if (halName_ == HDI_ID_INFO_VOIP) {
813 param.type = AUDIO_IN_COMMUNICATION;
814 param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_VOIP));
815 }
816 param.format = ConvertToHdiFormat(attr_.format);
817 param.frameSize = PcmFormatToBit(attr_.format) * param.channelCount / PCM_8_BIT;
818 if (param.frameSize != 0) {
819 param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
820 }
821 }
822
InitDeviceDesc(struct AudioDeviceDescriptor & deviceDesc)823 void AudioRenderSink::InitDeviceDesc(struct AudioDeviceDescriptor &deviceDesc)
824 {
825 if (halName_ == HDI_ID_INFO_USB) {
826 deviceDesc.desc = const_cast<char *>(address_.c_str());
827 } else {
828 deviceDesc.desc = const_cast<char *>(attr_.address.c_str());
829 }
830 deviceDesc.pins = GetAudioPortPin();
831 if (halName_ == HDI_ID_INFO_USB) {
832 deviceDesc.pins = PIN_OUT_USB_HEADSET;
833 } else if (halName_ == HDI_ID_INFO_DP) {
834 deviceDesc.pins = PIN_OUT_DP;
835 }
836 }
837
InitSceneDesc(struct AudioSceneDescriptor & sceneDesc,AudioScene audioScene)838 void AudioRenderSink::InitSceneDesc(struct AudioSceneDescriptor &sceneDesc, AudioScene audioScene)
839 {
840 sceneDesc.scene.id = GetAudioCategory(audioScene);
841 if (halName_ == HDI_ID_INFO_DIRECT) {
842 sceneDesc.scene.id = AUDIO_DIRECT;
843 } else if (halName_ == HDI_ID_INFO_VOIP) {
844 sceneDesc.scene.id = AUDIO_IN_COMMUNICATION;
845 }
846
847 AudioPortPin port = GetAudioPortPin();
848 if (halName_ == HDI_ID_INFO_USB) {
849 port = PIN_OUT_USB_HEADSET;
850 } else if (halName_ == HDI_ID_INFO_DP) {
851 port = PIN_OUT_DP;
852 }
853 AUDIO_DEBUG_LOG("port: %{public}d", port);
854 sceneDesc.desc.pins = port;
855 sceneDesc.desc.desc = const_cast<char *>("");
856 }
857
858 // LCOV_EXCL_START
SetAudioRouteInfoForEnhanceChain(void)859 void AudioRenderSink::SetAudioRouteInfoForEnhanceChain(void)
860 {
861 int32_t engineFlag = GetEngineFlag();
862 if (engineFlag != 1) {
863 AudioEnhanceChainManager *audioEnhanceChainManager = AudioEnhanceChainManager::GetInstance();
864 CHECK_AND_RETURN_LOG(audioEnhanceChainManager != nullptr, "audioEnhanceChainManager is nullptr");
865 if (halName_ == HDI_ID_INFO_USB) {
866 audioEnhanceChainManager->SetOutputDevice(renderId_, DEVICE_TYPE_USB_ARM_HEADSET);
867 } else if (halName_ == HDI_ID_INFO_DP) {
868 audioEnhanceChainManager->SetOutputDevice(renderId_, DEVICE_TYPE_DP);
869 } else {
870 audioEnhanceChainManager->SetOutputDevice(renderId_, currentActiveDevice_);
871 }
872 }
873 }
874 // LCOV_EXCL_STOP
875
CreateRender(void)876 int32_t AudioRenderSink::CreateRender(void)
877 {
878 Trace trace("AudioRenderSink::CreateRender");
879
880 struct AudioSampleAttributes param;
881 struct AudioDeviceDescriptor deviceDesc;
882 InitAudioSampleAttr(param);
883 InitDeviceDesc(deviceDesc);
884
885 AUDIO_INFO_LOG("create render, halName: %{public}s, rate: %{public}u, channel: %{public}u, format: %{public}u, "
886 "devicePin: %{public}u, desc: %{public}s", halName_.c_str(), param.sampleRate, param.channelCount, param.format,
887 deviceDesc.pins, deviceDesc.desc);
888 HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
889 std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
890 CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
891 void *render = deviceManager->CreateRender(adapterNameCase_, ¶m, &deviceDesc, hdiRenderId_);
892 audioRender_ = static_cast<struct IAudioRender *>(render);
893 CHECK_AND_RETURN_RET(audioRender_ != nullptr, ERR_NOT_STARTED);
894 SetAudioRouteInfoForEnhanceChain();
895
896 AUDIO_INFO_LOG("create render success, hdiRenderId_: %{public}u, desc: %{public}s", hdiRenderId_, deviceDesc.desc);
897 return SUCCESS;
898 }
899
DoSetOutputRoute(std::vector<DeviceType> & outputDevices)900 int32_t AudioRenderSink::DoSetOutputRoute(std::vector<DeviceType> &outputDevices)
901 {
902 HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
903 std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
904 CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
905 int32_t ret = deviceManager->SetOutputRoute(adapterNameCase_, outputDevices,
906 GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_PRIMARY));
907 return ret;
908 }
909
InitRender(void)910 int32_t AudioRenderSink::InitRender(void)
911 {
912 AUDIO_INFO_LOG("start, halName: %{public}s", halName_.c_str());
913 Trace trace("AudioRenderSink::InitRender");
914 if (renderInited_) {
915 AUDIO_INFO_LOG("render already inited");
916 return SUCCESS;
917 }
918
919 int32_t ret = CreateRender();
920 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create render fail");
921 if (openSpeaker_) {
922 ret = SUCCESS;
923 std::vector<DeviceType> outputDevices;
924 if (halName_ == HDI_ID_INFO_USB) {
925 outputDevices.push_back(DEVICE_TYPE_USB_ARM_HEADSET);
926 ret = UpdateActiveDevice(outputDevices);
927 } else if (halName_ == HDI_ID_INFO_DP) {
928 outputDevices.push_back(DEVICE_TYPE_DP);
929 ret = UpdateActiveDevice(outputDevices);
930 } else if (halName_ == HDI_ID_INFO_VOIP) {
931 // voip hal do not need to SetOutputRoute when create render, will SetOutputRoute when start stream
932 AUDIO_INFO_LOG("voip hal do not need to SetOutputRoute when create render");
933 } else {
934 DeviceType type = static_cast<DeviceType>(attr_.deviceType);
935 if (type == DEVICE_TYPE_INVALID) {
936 type = DEVICE_TYPE_SPEAKER;
937 }
938 outputDevices.push_back(type);
939 ret = UpdateActiveDevice(outputDevices);
940 }
941 if (ret != SUCCESS) {
942 AUDIO_WARNING_LOG("update route fail, ret: %{public}d", ret);
943 }
944 }
945 renderInited_ = true;
946 return SUCCESS;
947 }
948
InitLatencyMeasurement(void)949 void AudioRenderSink::InitLatencyMeasurement(void)
950 {
951 if (!AudioLatencyMeasurement::CheckIfEnabled()) {
952 return;
953 }
954
955 AUDIO_INFO_LOG("in");
956 signalDetectAgent_ = std::make_shared<SignalDetectAgent>();
957 CHECK_AND_RETURN_LOG(signalDetectAgent_ != nullptr, "signalDetectAgent is nullptr");
958 signalDetectAgent_->sampleFormat_ = attr_.format;
959 signalDetectAgent_->formatByteSize_ = GetFormatByteSize(attr_.format);
960 signalDetected_ = false;
961 }
962
DeInitLatencyMeasurement(void)963 void AudioRenderSink::DeInitLatencyMeasurement(void)
964 {
965 signalDetectAgent_ = nullptr;
966 }
967
CheckLatencySignal(uint8_t * data,size_t len)968 void AudioRenderSink::CheckLatencySignal(uint8_t *data, size_t len)
969 {
970 CHECK_AND_RETURN(signalDetectAgent_ != nullptr);
971 uint32_t byteSize = static_cast<uint32_t>(GetFormatByteSize(attr_.format));
972 size_t newlyCheckedTime = len / (attr_.sampleRate / MILLISECOND_PER_SECOND) /
973 (byteSize * sizeof(uint8_t) * attr_.channel);
974 signalDetectedTime_ += newlyCheckedTime;
975 if (signalDetectedTime_ >= MILLISECOND_PER_SECOND && signalDetectAgent_->signalDetected_ &&
976 !signalDetectAgent_->dspTimestampGot_) {
977 AudioParamKey key = NONE;
978 std::string condition = "debug_audio_latency_measurement";
979 HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
980 std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
981 CHECK_AND_RETURN(deviceManager != nullptr);
982 std::string value = deviceManager->GetAudioParameter(adapterNameCase_, key, condition);
983
984 LatencyMonitor::GetInstance().UpdateDspTime(value.c_str());
985 LatencyMonitor::GetInstance().UpdateSinkOrSourceTime(true, signalDetectAgent_->lastPeakBufferTime_);
986 LatencyMonitor::GetInstance().ShowTimestamp(true);
987 signalDetectAgent_->dspTimestampGot_ = true;
988 signalDetectAgent_->signalDetected_ = false;
989 }
990 signalDetected_ = signalDetectAgent_->CheckAudioData(data, len);
991 if (signalDetected_) {
992 AUDIO_INFO_LOG("signal detected");
993 signalDetectedTime_ = 0;
994 }
995 }
996
AdjustStereoToMono(char * data,uint64_t len)997 void AudioRenderSink::AdjustStereoToMono(char *data, uint64_t len)
998 {
999 // only stereo is supported now (stereo channel count is 2)
1000 CHECK_AND_RETURN_LOG(attr_.channel == STEREO_CHANNEL_COUNT, "unsupport, channel: %{public}d", attr_.channel);
1001
1002 switch (attr_.format) {
1003 case SAMPLE_U8:
1004 AdjustStereoToMonoForPCM8Bit(reinterpret_cast<int8_t *>(data), len);
1005 break;
1006 case SAMPLE_S16LE:
1007 AdjustStereoToMonoForPCM16Bit(reinterpret_cast<int16_t *>(data), len);
1008 break;
1009 case SAMPLE_S24LE:
1010 AdjustStereoToMonoForPCM24Bit(reinterpret_cast<uint8_t *>(data), len);
1011 break;
1012 case SAMPLE_S32LE:
1013 AdjustStereoToMonoForPCM32Bit(reinterpret_cast<int32_t *>(data), len);
1014 break;
1015 default:
1016 // if the audio format is unsupported, the audio data will not be changed
1017 AUDIO_ERR_LOG("unsupport, format: %{public}d", attr_.format);
1018 break;
1019 }
1020 }
1021
AdjustAudioBalance(char * data,uint64_t len)1022 void AudioRenderSink::AdjustAudioBalance(char *data, uint64_t len)
1023 {
1024 // only stereo is supported now (stereo channel count is 2)
1025 CHECK_AND_RETURN_LOG(attr_.channel == STEREO_CHANNEL_COUNT, "unsupport, channel: %{public}d", attr_.channel);
1026
1027 switch (attr_.format) {
1028 case SAMPLE_U8:
1029 // this function needs further tested for usability
1030 AdjustAudioBalanceForPCM8Bit(reinterpret_cast<int8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
1031 break;
1032 case SAMPLE_S16LE:
1033 AdjustAudioBalanceForPCM16Bit(reinterpret_cast<int16_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
1034 break;
1035 case SAMPLE_S24LE:
1036 // this function needs further tested for usability
1037 AdjustAudioBalanceForPCM24Bit(reinterpret_cast<uint8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
1038 break;
1039 case SAMPLE_S32LE:
1040 AdjustAudioBalanceForPCM32Bit(reinterpret_cast<int32_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
1041 break;
1042 default:
1043 // if the audio format is unsupported, the audio data will not be changed
1044 AUDIO_ERR_LOG("unsupport, format: %{public}d", attr_.format);
1045 break;
1046 }
1047 }
1048
CheckUpdateState(char * data,uint64_t len)1049 void AudioRenderSink::CheckUpdateState(char *data, uint64_t len)
1050 {
1051 if (startUpdate_) {
1052 if (renderFrameNum_ == 0) {
1053 last10FrameStartTime_ = ClockTime::GetCurNano();
1054 }
1055 renderFrameNum_++;
1056 maxAmplitude_ = UpdateMaxAmplitude(static_cast<ConvertHdiFormat>(attr_.format), data, len);
1057 if (renderFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) {
1058 renderFrameNum_ = 0;
1059 if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) {
1060 startUpdate_ = false;
1061 maxAmplitude_ = 0;
1062 }
1063 }
1064 }
1065 }
1066
GetAttrInfoStr(const struct AudioSampleAttributes & attrInfo)1067 std::string AudioRenderSink::GetAttrInfoStr(const struct AudioSampleAttributes &attrInfo)
1068 {
1069 CHECK_AND_RETURN_RET_LOG(attrInfo.sampleRate > 0, "", "invalid rate: %{public}d", attrInfo.sampleRate);
1070 CHECK_AND_RETURN_RET_LOG(attrInfo.format > 0, "", "invalid format: %{public}d", attrInfo.format);
1071 CHECK_AND_RETURN_RET_LOG(attrInfo.channelCount > 0, "", "invalid channel: %{public}d", attrInfo.channelCount);
1072
1073 uint32_t bufferSize = attrInfo.sampleRate * attrInfo.format * attrInfo.channelCount *
1074 BUFFER_CALC_20MS / BUFFER_CALC_1000MS;
1075 std::string attrInfoStr = "rate=" + std::to_string(attrInfo.sampleRate) + " format=" +
1076 ParseAudioFormatToStr(attrInfo.format) + " channels=" + std::to_string(attrInfo.channelCount) +
1077 " buffer_size=" + std::to_string(bufferSize);
1078 AUDIO_INFO_LOG("attrInfoStr: %{public}s", attrInfoStr.c_str());
1079 return attrInfoStr;
1080 }
1081
UpdateDPAttr(const std::string & dpInfo)1082 int32_t AudioRenderSink::UpdateDPAttr(const std::string &dpInfo)
1083 {
1084 CHECK_AND_RETURN_RET_LOG(!dpInfo.empty(), ERR_INVALID_PARAM, "dp info is empty");
1085
1086 auto sinkRate_begin = dpInfo.find("rate=");
1087 auto sinkRate_end = dpInfo.find_first_of(" ", sinkRate_begin);
1088 std::string sampleRateStr = dpInfo.substr(sinkRate_begin + std::strlen("rate="),
1089 sinkRate_end - sinkRate_begin - std::strlen("rate="));
1090
1091 auto sinkBuffer_begin = dpInfo.find("buffer_size=");
1092 auto sinkBuffer_end = dpInfo.find_first_of(" ", sinkBuffer_begin);
1093 std::string bufferSizeStr = dpInfo.substr(sinkBuffer_begin + std::strlen("buffer_size="),
1094 sinkBuffer_end - sinkBuffer_begin - std::strlen("buffer_size="));
1095
1096 auto sinkChannel_begin = dpInfo.find("channels=");
1097 auto sinkChannel_end = dpInfo.find_first_of(" ", sinkChannel_begin);
1098 std::string channelStr = dpInfo.substr(sinkChannel_begin + std::strlen("channels="),
1099 sinkChannel_end - sinkChannel_begin - std::strlen("channels="));
1100
1101 auto address_begin = dpInfo.find("address=");
1102 auto address_end = dpInfo.find_first_of(" ", address_begin);
1103 std::string addressStr = dpInfo.substr(address_begin + std::strlen("address="),
1104 address_end - address_begin - std::strlen("address="));
1105
1106 bool ret = StringConverter(sampleRateStr, attr_.sampleRate);
1107 CHECK_AND_RETURN_RET_LOG(ret, ERR_INVALID_PARAM, "convert fail, sampleRate: %{public}s", sampleRateStr.c_str());
1108 ret = StringConverter(channelStr, attr_.channel);
1109 CHECK_AND_RETURN_RET_LOG(ret, ERR_INVALID_PARAM, "convert fail, channel: %{public}s", channelStr.c_str());
1110
1111 attr_.address = addressStr;
1112 uint32_t formatByte = 0;
1113 if (attr_.channel <= 0 || attr_.sampleRate <= 0 || bufferSizeStr.empty()) {
1114 AUDIO_ERR_LOG("check attr fail, channel: %{public}d, sampleRate: %{public}d", attr_.channel, attr_.sampleRate);
1115 } else {
1116 uint32_t bufferSize = 0;
1117 ret = StringConverter(bufferSizeStr, bufferSize);
1118 CHECK_AND_RETURN_RET_LOG(ret, ERR_INVALID_PARAM, "convert fail, bufferSize: %{public}s", bufferSizeStr.c_str());
1119 formatByte = bufferSize * BUFFER_CALC_1000MS / BUFFER_CALC_20MS / attr_.channel / attr_.sampleRate;
1120 }
1121
1122 attr_.format = static_cast<AudioSampleFormat>(ConvertByteToAudioFormat(formatByte));
1123
1124 AUDIO_DEBUG_LOG("sampleRate: %{public}d, format: %{public}d, channelCount: %{public}d, address: %{public}s",
1125 attr_.sampleRate, attr_.format, attr_.channel, addressStr.c_str());
1126
1127 adapterNameCase_ = "dp";
1128 openSpeaker_ = 0;
1129 return SUCCESS;
1130 }
1131
GetDPDeviceInfo(const std::string & condition)1132 std::string AudioRenderSink::GetDPDeviceInfo(const std::string &condition)
1133 {
1134 int32_t ret = UpdateDPAttr(condition);
1135 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, "", "init attr fail");
1136
1137 ret = InitRender();
1138 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && audioRender_ != nullptr, "", "init render fail");
1139
1140 struct AudioSampleAttributes attrInfo = {};
1141 ret = audioRender_->GetSampleAttributes(audioRender_, &attrInfo);
1142 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, "", "get sample attr fail");
1143
1144 AUDIO_DEBUG_LOG("sampleRate: %{public}d, format: %{public}d, channelCount: %{public}d, size: %{public}d",
1145 attrInfo.sampleRate, attrInfo.format, attrInfo.channelCount, attrInfo.frameSize);
1146 return GetAttrInfoStr(attrInfo);
1147 }
1148
GetRouting(void) const1149 std::string AudioRenderSink::GetRouting(void) const
1150 {
1151 switch (currentActiveDevice_) {
1152 case DEVICE_TYPE_EARPIECE:
1153 return "1";
1154 case DEVICE_TYPE_SPEAKER:
1155 return "2";
1156 case DEVICE_TYPE_WIRED_HEADSET:
1157 return "4";
1158 case DEVICE_TYPE_USB_ARM_HEADSET:
1159 return "67108864";
1160 case DEVICE_TYPE_USB_HEADSET:
1161 return "545259520";
1162 case DEVICE_TYPE_BLUETOOTH_SCO:
1163 return "16";
1164 case DEVICE_TYPE_BLUETOOTH_A2DP:
1165 return "128";
1166 default:
1167 break;
1168 }
1169 return "0";
1170 }
1171
WriteSmartPAStatusSysEvent(int32_t status)1172 void AudioRenderSink::WriteSmartPAStatusSysEvent(int32_t status)
1173 {
1174 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
1175 Media::MediaMonitor::AUDIO, Media::MediaMonitor::SMARTPA_STATUS,
1176 Media::MediaMonitor::BEHAVIOR_EVENT);
1177 bean->Add("STATUS", status);
1178 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
1179 }
1180
1181 // must be called with sinkMutex_ held
UpdateSinkState(bool started)1182 void AudioRenderSink::UpdateSinkState(bool started)
1183 {
1184 callback_.OnRenderSinkStateChange(GetUniqueId(), started);
1185 }
1186
UpdatePrimaryConnectionState(uint32_t operation)1187 int32_t AudioRenderSink::UpdatePrimaryConnectionState(uint32_t operation)
1188 {
1189 if (operation == DATA_LINK_CONNECTING) {
1190 AUDIO_INFO_LOG("Primary sink is connecting");
1191 isDataLinkConnected_ = false;
1192 }
1193 if (operation == DATA_LINK_CONNECTED) {
1194 AUDIO_INFO_LOG("Primary sink is connected");
1195 isDataLinkConnected_ = true;
1196 dataConnectionCV_.notify_all();
1197 }
1198 return SUCCESS;
1199 }
1200
SetDmDeviceType(uint16_t dmDeviceType,DeviceType deviceType)1201 void AudioRenderSink::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType)
1202 {
1203 std::lock_guard<std::mutex> lock(sinkMutex_);
1204 const auto &it = dmDeviceTypeMap_.find(deviceType);
1205 bool isDmDeviceTypeUpdated = it == dmDeviceTypeMap_.end() || it->second != dmDeviceType;
1206 dmDeviceTypeMap_[deviceType] = dmDeviceType;
1207 HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
1208 std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
1209 CHECK_AND_RETURN_LOG(deviceManager != nullptr, "deviceManager is nullptr");
1210 deviceManager->SetDmDeviceType(dmDeviceType, deviceType);
1211
1212 CHECK_AND_RETURN(isDmDeviceTypeUpdated);
1213 std::vector<DeviceType> outputDevices;
1214 outputDevices.push_back(currentActiveDevice_);
1215 AUDIO_INFO_LOG("dm deviceType update, need update output port pin");
1216 int32_t ret = DoSetOutputRoute(outputDevices);
1217 CHECK_AND_RETURN_LOG(ret == SUCCESS, "DoSetOutputRoute fails");
1218 }
1219
WaitForDataLinkConnected()1220 void AudioRenderSink::WaitForDataLinkConnected()
1221 {
1222 std::unique_lock<std::mutex> dataConnectionWaitLock(dataConnectionMutex_);
1223 if (!isDataLinkConnected_ && (halName_ == "primary") && (sinkType_ == ADAPTER_TYPE_PRIMARY)) {
1224 AUDIO_INFO_LOG("data-connection blocking starts");
1225 bool stopWaiting = dataConnectionCV_.wait_for(
1226 dataConnectionWaitLock, std::chrono::milliseconds(DATA_CONNECTION_TIMEOUT_IN_MS), [this] {
1227 return isDataLinkConnected_;
1228 });
1229 if (stopWaiting) {
1230 AUDIO_INFO_LOG("data-connection blocking ends");
1231 } else {
1232 AUDIO_WARNING_LOG("data-connection time out, start RenderFrame anyway.");
1233 }
1234 isDataLinkConnected_ = true;
1235 }
1236 dataConnectionWaitLock.unlock();
1237 }
1238
1239 } // namespace AudioStandard
1240 } // namespace OHOS
1241