1 /*
2 * Copyright (c) 2023-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 #ifndef LOG_TAG
16 #define LOG_TAG "MultiChannelRendererSinkInner"
17 #endif
18
19 #include "multichannel_audio_renderer_sink.h"
20
21 #include <atomic>
22 #include <cstring>
23 #include <cinttypes>
24 #include <condition_variable>
25 #include <dlfcn.h>
26 #include <string>
27 #include <unistd.h>
28 #include <mutex>
29
30 #include "securec.h"
31 #ifdef FEATURE_POWER_MANAGER
32 #include "power_mgr_client.h"
33 #include "running_lock.h"
34 #include "audio_running_lock_manager.h"
35 #endif
36 #include "v4_0/iaudio_manager.h"
37
38 #include "audio_errors.h"
39 #include "audio_hdi_log.h"
40 #include "parameters.h"
41 #include "volume_tools.h"
42 #include "audio_dump_pcm.h"
43 #include "audio_performance_monitor.h"
44
45 using namespace std;
46
47 namespace OHOS {
48 namespace AudioStandard {
49 namespace {
50 const int32_t HALF_FACTOR = 2;
51 const int32_t MAX_AUDIO_ADAPTER_NUM = 5;
52 const float DEFAULT_VOLUME_LEVEL = 1.0f;
53 const uint32_t AUDIO_SAMPLE_RATE_48K = 48000;
54 const uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 4096;
55 const uint32_t INT_32_MAX = 0x7fffffff;
56 const uint32_t PCM_8_BIT = 8;
57 const uint32_t PCM_16_BIT = 16;
58 const uint32_t PCM_24_BIT = 24;
59 const uint32_t PCM_32_BIT = 32;
60 const uint32_t STEREO_CHANNEL_COUNT = 2;
61 const uint16_t GET_MAX_AMPLITUDE_FRAMES_THRESHOLD = 10;
62
63 #ifdef FEATURE_POWER_MANAGER
64 constexpr int32_t RUNNINGLOCK_LOCK_TIMEOUTMS_LASTING = -1;
65 #endif
66 const int32_t SLEEP_TIME_FOR_RENDER_EMPTY = 120;
67 }
68 class MultiChannelRendererSinkInner : public MultiChannelRendererSink {
69 public:
70 int32_t Init(const IAudioSinkAttr &attr) override;
71 bool IsInited(void) override;
72 void DeInit(void) override;
73
74 int32_t Flush(void) override;
75 int32_t Pause(void) override;
76 int32_t Reset(void) override;
77 int32_t Resume(void) override;
78 int32_t Start(void) override;
79 int32_t Stop(void) override;
80
81 int32_t SuspendRenderSink(void) override;
82 int32_t RestoreRenderSink(void) override;
83
84 int32_t RenderFrame(char &data, uint64_t len, uint64_t &writeLen) override;
85 int32_t SetVolume(float left, float right) override;
86 int32_t GetVolume(float &left, float &right) override;
87 int32_t SetVoiceVolume(float volume) override;
88 int32_t GetLatency(uint32_t *latency) override;
89 int32_t GetTransactionId(uint64_t *transactionId) override;
90 int32_t GetAudioScene() override;
91 int32_t SetAudioScene(AudioScene audioScene, std::vector<DeviceType> &activeDevices) override;
92
93 void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override;
94 std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override;
95 void RegisterAudioSinkCallback(IAudioSinkCallback* callback) override;
96 int32_t GetPresentationPosition(uint64_t& frames, int64_t& timeSec, int64_t& timeNanoSec) override;
97
98 void SetAudioMonoState(bool audioMono) override;
99 void SetAudioBalanceValue(float audioBalance) override;
100
101 int32_t SetOutputRoutes(std::vector<DeviceType> &outputDevices) override;
102 int32_t SetOutputRoute(DeviceType outputDevice, AudioPortPin &outputPortPin);
103
104 int32_t Preload(const std::string &usbInfoStr) override;
105 float GetMaxAmplitude() override;
106
107 void ResetOutputRouteForDisconnect(DeviceType device) override;
108 int32_t SetPaPower(int32_t flag) override;
109 int32_t SetPriPaPower() override;
110
111 int32_t UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size) final;
112 int32_t UpdateAppsUid(const std::vector<int32_t> &appsUid) final;
113 void UpdateSinkState(bool started);
114 int32_t GetRenderId(uint32_t &renderId) const override;
115
116 explicit MultiChannelRendererSinkInner(const std::string &halName = "multichannel");
117 ~MultiChannelRendererSinkInner();
118 private:
119 IAudioSinkAttr attr_ = {};
120 bool sinkInited_ = false;
121 bool adapterInited_ = false;
122 bool renderInited_ = false;
123 bool started_ = false;
124 bool paused_ = false;
125 float leftVolume_ = 0;
126 float rightVolume_ = 0;
127 int32_t routeHandle_ = -1;
128 int32_t logMode_ = 0;
129 uint32_t openSpeaker_ = 0;
130 uint32_t renderId_ = 0;
131 uint32_t sinkId_ = 0;
132 std::string adapterNameCase_ = "";
133 struct IAudioManager *audioManager_ = nullptr;
134 struct IAudioAdapter *audioAdapter_ = nullptr;
135 struct IAudioRender *audioRender_ = nullptr;
136 IAudioSinkCallback *callback_ = nullptr;
137 std::string halName_;
138 struct AudioAdapterDescriptor adapterDesc_ = {};
139 struct AudioPort audioPort_ = {};
140 bool audioMonoState_ = false;
141 bool audioBalanceState_ = false;
142 float leftBalanceCoef_ = 1.0f;
143 float rightBalanceCoef_ = 1.0f;
144 // for get amplitude
145 float maxAmplitude_ = 0;
146 int64_t lastGetMaxAmplitudeTime_ = 0;
147 int64_t last10FrameStartTime_ = 0;
148 bool startUpdate_ = false;
149 int renderFrameNum_ = 0;
150 std::string logUtilsTag_ = "MultiChannelRendererSinkInner::RenderFrame";
151 mutable int64_t volumeDataCount_ = 0;
152 #ifdef FEATURE_POWER_MANAGER
153 std::shared_ptr<AudioRunningLockManager<PowerMgr::RunningLock>> runningLockManager_;
154 #endif
155 // for sink state
156 std::mutex sinkMutex_;
157 // for device switch
158 std::atomic<bool> inSwitch_ = false;
159 std::atomic<int32_t> renderEmptyFrameCount_ = 0;
160 std::mutex switchMutex_;
161 std::condition_variable switchCV_;
162
163 private:
164 int32_t CreateRender(const struct AudioPort &renderPort);
165 int32_t InitAudioManager();
166 AudioFormat ConvertToHdiFormat(HdiAdapterFormat format);
167 void AdjustStereoToMono(char *data, uint64_t len);
168 void AdjustAudioBalance(char *data, uint64_t len);
169
170 int32_t UpdateUsbAttrs(const std::string &usbInfoStr);
171 int32_t InitAdapter();
172 int32_t InitRender();
173 int32_t CheckHdiFuncWhenStart();
174
175 void CheckUpdateState(char *frame, uint64_t replyBytes);
176 void RenderEmptyFrame(char &data, uint64_t len);
177 void InitAudioRouteNode(AudioRouteNode &source, AudioRouteNode &sink);
178 void DumpData(std::string fileName, void *buffer, size_t len);
179 std::string dumpFileName_ = "";
180 FILE *dumpFile_ = nullptr;
181 DeviceType currentActiveDevice_ = DEVICE_TYPE_NONE;
182 AudioScene currentAudioScene_ = AudioScene::AUDIO_SCENE_INVALID;
183 };
184
MultiChannelRendererSinkInner(const std::string & halName)185 MultiChannelRendererSinkInner::MultiChannelRendererSinkInner(const std::string &halName)
186 : sinkInited_(false), adapterInited_(false), renderInited_(false), started_(false), paused_(false),
187 leftVolume_(DEFAULT_VOLUME_LEVEL), rightVolume_(DEFAULT_VOLUME_LEVEL), openSpeaker_(0),
188 audioManager_(nullptr), audioAdapter_(nullptr), audioRender_(nullptr), halName_(halName)
189 {
190 AUDIO_INFO_LOG("MultiChannelRendererSinkInner");
191 }
192
~MultiChannelRendererSinkInner()193 MultiChannelRendererSinkInner::~MultiChannelRendererSinkInner()
194 {
195 AUDIO_INFO_LOG("~MultiChannelRendererSinkInner");
196 AudioPerformanceMonitor::GetInstance().DeleteOvertimeMonitor(ADAPTER_TYPE_MULTICHANNEL);
197 }
198
GetInstance(const std::string & halName)199 MultiChannelRendererSink *MultiChannelRendererSink::GetInstance(const std::string &halName)
200 {
201 static MultiChannelRendererSinkInner audioRenderer;
202 return &audioRenderer;
203 }
204
205 // LCOV_EXCL_START
SwitchAdapterRender(struct AudioAdapterDescriptor * descs,const string & adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort & renderPort,uint32_t size)206 static int32_t SwitchAdapterRender(struct AudioAdapterDescriptor *descs, const string &adapterNameCase,
207 enum AudioPortDirection portFlag, struct AudioPort &renderPort, uint32_t size)
208 {
209 if (descs == nullptr) {
210 return ERROR;
211 }
212 for (uint32_t index = 0; index < size; index++) {
213 struct AudioAdapterDescriptor *desc = &descs[index];
214 if (desc == nullptr || desc->adapterName == nullptr) {
215 continue;
216 }
217 AUDIO_DEBUG_LOG("index %{public}u, adapterName %{public}s", index, desc->adapterName);
218 if (strcmp(desc->adapterName, adapterNameCase.c_str())) {
219 continue;
220 }
221 for (uint32_t port = 0; port < desc->portsLen; port++) {
222 // Only find out the port of out in the sound card
223 if (desc->ports[port].dir == portFlag) {
224 renderPort = desc->ports[port];
225 return index;
226 }
227 }
228 }
229 AUDIO_ERR_LOG("switch adapter render fail");
230 return ERR_INVALID_INDEX;
231 }
232
233
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)234 void MultiChannelRendererSinkInner::SetAudioParameter(const AudioParamKey key, const std::string &condition,
235 const std::string &value)
236 {
237 AUDIO_INFO_LOG("SetAudioParameter: key %{public}d, condition: %{public}s, value: %{public}s", key,
238 condition.c_str(), value.c_str());
239 AudioExtParamKey hdiKey = AudioExtParamKey(key);
240 if (audioAdapter_ == nullptr) {
241 AUDIO_ERR_LOG("SetAudioParameter failed, audioAdapter_ is null");
242 return;
243 }
244 int32_t ret = audioAdapter_->SetExtraParams(audioAdapter_, hdiKey, condition.c_str(), value.c_str());
245 if (ret != SUCCESS) {
246 AUDIO_ERR_LOG("SetAudioParameter failed, error code: %d", ret);
247 }
248 }
249
GetAudioParameter(const AudioParamKey key,const std::string & condition)250 std::string MultiChannelRendererSinkInner::GetAudioParameter(const AudioParamKey key, const std::string &condition)
251 {
252 AUDIO_INFO_LOG("GetAudioParameter: key %{public}d, condition: %{public}s", key,
253 condition.c_str());
254 if (condition == "get_usb_info") {
255 // Init adapter to get parameter before load sink module (need fix)
256 adapterNameCase_ = "usb";
257 int32_t ret = InitAdapter();
258 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, "", "Init adapter failed for get usb info param");
259 }
260
261 AudioExtParamKey hdiKey = AudioExtParamKey(key);
262 char value[DumpFileUtil::PARAM_VALUE_LENTH];
263 if (audioAdapter_ == nullptr) {
264 AUDIO_ERR_LOG("GetAudioParameter failed, audioAdapter_ is null");
265 return "";
266 }
267 int32_t ret = audioAdapter_->GetExtraParams(audioAdapter_, hdiKey, condition.c_str(),
268 value, DumpFileUtil::PARAM_VALUE_LENTH);
269 if (ret != SUCCESS) {
270 AUDIO_ERR_LOG("GetAudioParameter failed, error code: %d", ret);
271 return "";
272 }
273 return value;
274 }
275
SetAudioMonoState(bool audioMono)276 void MultiChannelRendererSinkInner::SetAudioMonoState(bool audioMono)
277 {
278 audioMonoState_ = audioMono;
279 }
280
SetAudioBalanceValue(float audioBalance)281 void MultiChannelRendererSinkInner::SetAudioBalanceValue(float audioBalance)
282 {
283 // reset the balance coefficient value firstly
284 leftBalanceCoef_ = 1.0f;
285 rightBalanceCoef_ = 1.0f;
286
287 if (std::abs(audioBalance - 0.0f) <= std::numeric_limits<float>::epsilon()) {
288 // audioBalance is equal to 0.0f
289 audioBalanceState_ = false;
290 } else {
291 // audioBalance is not equal to 0.0f
292 audioBalanceState_ = true;
293 // calculate the balance coefficient
294 if (audioBalance > 0.0f) {
295 leftBalanceCoef_ -= audioBalance;
296 } else if (audioBalance < 0.0f) {
297 rightBalanceCoef_ += audioBalance;
298 }
299 }
300 }
301
AdjustStereoToMono(char * data,uint64_t len)302 void MultiChannelRendererSinkInner::AdjustStereoToMono(char *data, uint64_t len)
303 {
304 if (attr_.channel != STEREO_CHANNEL_COUNT) {
305 // only stereo is surpported now (stereo channel count is 2)
306 AUDIO_ERR_LOG("AdjustStereoToMono: Unsupported channel number: %{public}d", attr_.channel);
307 return;
308 }
309
310 switch (attr_.format) {
311 case SAMPLE_U8: {
312 // this function needs to be further tested for usability
313 AdjustStereoToMonoForPCM8Bit(reinterpret_cast<int8_t *>(data), len);
314 break;
315 }
316 case SAMPLE_S16: {
317 AdjustStereoToMonoForPCM16Bit(reinterpret_cast<int16_t *>(data), len);
318 break;
319 }
320 case SAMPLE_S24: {
321 // this function needs to be further tested for usability
322 AdjustStereoToMonoForPCM24Bit(reinterpret_cast<uint8_t *>(data), len);
323 break;
324 }
325 case SAMPLE_S32: {
326 AdjustStereoToMonoForPCM32Bit(reinterpret_cast<int32_t *>(data), len);
327 break;
328 }
329 default: {
330 // if the audio format is unsupported, the audio data will not be changed
331 AUDIO_ERR_LOG("AdjustStereoToMono: Unsupported audio format: %{public}d", attr_.format);
332 break;
333 }
334 }
335 }
336
AdjustAudioBalance(char * data,uint64_t len)337 void MultiChannelRendererSinkInner::AdjustAudioBalance(char *data, uint64_t len)
338 {
339 if (attr_.channel != STEREO_CHANNEL_COUNT) {
340 // only stereo is surpported now (stereo channel count is 2)
341 AUDIO_ERR_LOG("Unsupported channel number: %{public}d", attr_.channel);
342 return;
343 }
344
345 switch (attr_.format) {
346 case SAMPLE_U8: {
347 // this function needs to be further tested for usability
348 AdjustAudioBalanceForPCM8Bit(reinterpret_cast<int8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
349 break;
350 }
351 case SAMPLE_S16LE: {
352 AdjustAudioBalanceForPCM16Bit(reinterpret_cast<int16_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
353 break;
354 }
355 case SAMPLE_S24LE: {
356 // this function needs to be further tested for usability
357 AdjustAudioBalanceForPCM24Bit(reinterpret_cast<uint8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
358 break;
359 }
360 case SAMPLE_S32LE: {
361 AdjustAudioBalanceForPCM32Bit(reinterpret_cast<int32_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
362 break;
363 }
364 default: {
365 // if the audio format is unsupported, the audio data will not be changed
366 AUDIO_ERR_LOG("Unsupported audio format: %{public}d", attr_.format);
367 break;
368 }
369 }
370 }
371
IsInited()372 bool MultiChannelRendererSinkInner::IsInited()
373 {
374 return sinkInited_;
375 }
376
RegisterAudioSinkCallback(IAudioSinkCallback * callback)377 void MultiChannelRendererSinkInner::RegisterAudioSinkCallback(IAudioSinkCallback* callback)
378 {
379 std::lock_guard<std::mutex> lock(sinkMutex_);
380 if (callback_) {
381 AUDIO_INFO_LOG("AudioSinkCallback registered");
382 } else {
383 callback_ = callback;
384 AUDIO_INFO_LOG("Register AudioSinkCallback");
385 }
386 }
387
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)388 int32_t MultiChannelRendererSinkInner::GetPresentationPosition(uint64_t& frames, int64_t& timeSec, int64_t& timeNanoSec)
389 {
390 AUDIO_ERR_LOG("not supported.");
391 return ERR_INVALID_HANDLE;
392 }
393
DeInit()394 void MultiChannelRendererSinkInner::DeInit()
395 {
396 std::lock_guard<std::mutex> lock(sinkMutex_);
397 AUDIO_INFO_LOG("Mch DeInit.");
398 started_ = false;
399 sinkInited_ = false;
400
401 if (audioAdapter_ != nullptr) {
402 AUDIO_INFO_LOG("DestroyRender rendererid: %{public}u", renderId_);
403 audioAdapter_->DestroyRender(audioAdapter_, renderId_);
404 }
405 audioRender_ = nullptr;
406 renderInited_ = false;
407 audioManager_ = nullptr;
408 adapterInited_ = false;
409
410 DumpFileUtil::CloseDumpFile(&dumpFile_);
411 }
412
InitAttrs(struct AudioSampleAttributes & attrs)413 void InitAttrs(struct AudioSampleAttributes &attrs)
414 {
415 /* Initialization of audio parameters for playback */
416 attrs.channelCount = CHANNEL_6;
417 attrs.sampleRate = AUDIO_SAMPLE_RATE_48K;
418 attrs.interleaved = true;
419 attrs.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_MULTICHANNEL));
420 attrs.type = AUDIO_MULTI_CHANNEL;
421 attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
422 attrs.isBigEndian = false;
423 attrs.isSignedData = true;
424 attrs.stopThreshold = INT_32_MAX;
425 attrs.silenceThreshold = 0;
426 }
427
InitAudioManager()428 int32_t MultiChannelRendererSinkInner::InitAudioManager()
429 {
430 AUDIO_INFO_LOG("Initialize audio proxy manager");
431
432 audioManager_ = IAudioManagerGet(false);
433 if (audioManager_ == nullptr) {
434 return ERR_INVALID_HANDLE;
435 }
436
437 return 0;
438 }
439
PcmFormatToBits(enum AudioFormat format)440 uint32_t PcmFormatToBits(enum AudioFormat format)
441 {
442 switch (format) {
443 case AUDIO_FORMAT_TYPE_PCM_8_BIT:
444 return PCM_8_BIT;
445 case AUDIO_FORMAT_TYPE_PCM_16_BIT:
446 return PCM_16_BIT;
447 case AUDIO_FORMAT_TYPE_PCM_24_BIT:
448 return PCM_24_BIT;
449 case AUDIO_FORMAT_TYPE_PCM_32_BIT:
450 return PCM_32_BIT;
451 default:
452 AUDIO_INFO_LOG("Unkown format type,set it to default");
453 return PCM_24_BIT;
454 }
455 }
456
ConvertToHdiFormat(HdiAdapterFormat format)457 AudioFormat MultiChannelRendererSinkInner::ConvertToHdiFormat(HdiAdapterFormat format)
458 {
459 AudioFormat hdiFormat;
460 switch (format) {
461 case SAMPLE_U8:
462 hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
463 break;
464 case SAMPLE_S16:
465 hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
466 break;
467 case SAMPLE_S24:
468 hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
469 break;
470 case SAMPLE_S32:
471 hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
472 break;
473 default:
474 hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
475 break;
476 }
477
478 return hdiFormat;
479 }
480
CreateRender(const struct AudioPort & renderPort)481 int32_t MultiChannelRendererSinkInner::CreateRender(const struct AudioPort &renderPort)
482 {
483 int32_t ret;
484 struct AudioSampleAttributes param;
485 struct AudioDeviceDescriptor deviceDesc;
486 InitAttrs(param);
487 param.sampleRate = attr_.sampleRate;
488 param.channelCount = attr_.channel;
489 param.channelLayout = attr_.channelLayout;
490 param.format = ConvertToHdiFormat(attr_.format);
491 param.frameSize = PcmFormatToBits(param.format) * param.channelCount / PCM_8_BIT;
492 param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
493 deviceDesc.portId = renderPort.portId;
494 deviceDesc.desc = const_cast<char *>("");
495 deviceDesc.pins = PIN_OUT_SPEAKER;
496 if (halName_ == "usb") {
497 deviceDesc.pins = PIN_OUT_USB_HEADSET;
498 }
499 AUDIO_INFO_LOG("Create render halname: %{public}s format: %{public}d, sampleRate:%{public}u channel%{public}u",
500 halName_.c_str(), param.format, param.sampleRate, param.channelCount);
501 ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, ¶m, &audioRender_, &renderId_);
502 if (ret != 0 || audioRender_ == nullptr) {
503 AUDIO_ERR_LOG("AudioDeviceCreateRender failed.");
504 return ERR_NOT_STARTED;
505 }
506 AUDIO_INFO_LOG("Create success rendererid: %{public}u", renderId_);
507
508 return 0;
509 }
510
Init(const IAudioSinkAttr & attr)511 int32_t MultiChannelRendererSinkInner::Init(const IAudioSinkAttr &attr)
512 {
513 std::lock_guard<std::mutex> lock(sinkMutex_);
514 attr_ = attr;
515 adapterNameCase_ = attr_.adapterName;
516 openSpeaker_ = attr_.openMicSpeaker;
517 logMode_ = system::GetIntParameter("persist.multimedia.audiolog.switch", 0);
518 int32_t ret = InitAdapter();
519 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Init adapter failed");
520
521 ret = InitRender();
522 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Init render failed");
523
524 sinkInited_ = true;
525 GetRenderId(sinkId_);
526
527 return SUCCESS;
528 }
529
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)530 int32_t MultiChannelRendererSinkInner::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
531 {
532 int64_t stamp = ClockTime::GetCurNano();
533 int32_t ret;
534 if (audioRender_ == nullptr) {
535 AUDIO_ERR_LOG("Audio Render Handle is nullptr!");
536 return ERR_INVALID_HANDLE;
537 }
538
539 if (audioMonoState_) {
540 AdjustStereoToMono(&data, len);
541 }
542
543 if (audioBalanceState_) {
544 AdjustAudioBalance(&data, len);
545 }
546
547 DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(&data), len);
548 CheckUpdateState(&data, len);
549
550 if (inSwitch_) {
551 Trace traceInSwitch("AudioRendererSinkInner::RenderFrame::inSwitch");
552 writeLen = len;
553 return SUCCESS;
554 }
555
556 if (renderEmptyFrameCount_ > 0) {
557 RenderEmptyFrame(data, len);
558 }
559 BufferDesc tmpBuffer = {reinterpret_cast<uint8_t *>(&data), len, len};
560 AudioStreamInfo streamInfo(static_cast<AudioSamplingRate>(attr_.sampleRate), AudioEncodingType::ENCODING_PCM,
561 static_cast<AudioSampleFormat>(attr_.format), static_cast<AudioChannel>(attr_.channel));
562 VolumeTools::DfxOperation(tmpBuffer, streamInfo, logUtilsTag_, volumeDataCount_);
563 Trace trace("MchSinkInner::RenderFrame");
564
565 DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(&data), len);
566 DumpData(dumpFileName_, static_cast<void *>(&data), len);
567
568 ret = audioRender_->RenderFrame(audioRender_, reinterpret_cast<int8_t*>(&data), static_cast<uint32_t>(len),
569 &writeLen);
570 if (ret != 0) {
571 AUDIO_ERR_LOG("RenderFrame failed ret: %{public}x", ret);
572 return ERR_WRITE_FAILED;
573 }
574 AudioPerformanceMonitor::GetInstance().RecordTimeStamp(ADAPTER_TYPE_MULTICHANNEL, ClockTime::GetCurNano());
575 stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
576 if (logMode_) {
577 AUDIO_DEBUG_LOG("RenderFrame len[%{public}" PRIu64 "] cost[%{public}" PRId64 "]ms", len, stamp);
578 }
579 return SUCCESS;
580 }
581
CheckUpdateState(char * frame,uint64_t replyBytes)582 void MultiChannelRendererSinkInner::CheckUpdateState(char *frame, uint64_t replyBytes)
583 {
584 if (startUpdate_) {
585 if (renderFrameNum_ == 0) {
586 last10FrameStartTime_ = ClockTime::GetCurNano();
587 }
588 renderFrameNum_++;
589 maxAmplitude_ = UpdateMaxAmplitude(static_cast<ConvertHdiFormat>(attr_.format), frame, replyBytes);
590 if (renderFrameNum_ == GET_MAX_AMPLITUDE_FRAMES_THRESHOLD) {
591 renderFrameNum_ = 0;
592 if (last10FrameStartTime_ > lastGetMaxAmplitudeTime_) {
593 startUpdate_ = false;
594 maxAmplitude_ = 0;
595 }
596 }
597 }
598 }
599
RenderEmptyFrame(char & data,uint64_t len)600 void MultiChannelRendererSinkInner::RenderEmptyFrame(char &data, uint64_t len)
601 {
602 Trace traceEmpty("MchSinkInner::RenderFrame::renderEmpty");
603 if (memset_s(reinterpret_cast<void*>(&data), static_cast<size_t>(len), 0,
604 static_cast<size_t>(len)) != EOK) {
605 AUDIO_WARNING_LOG("call memset_s failed");
606 }
607 renderEmptyFrameCount_--;
608 if (renderEmptyFrameCount_ == 0) {
609 switchCV_.notify_all();
610 }
611 }
612
GetMaxAmplitude()613 float MultiChannelRendererSinkInner::GetMaxAmplitude()
614 {
615 lastGetMaxAmplitudeTime_ = ClockTime::GetCurNano();
616 startUpdate_ = true;
617 return maxAmplitude_;
618 }
619
Start(void)620 int32_t MultiChannelRendererSinkInner::Start(void)
621 {
622 std::lock_guard<std::mutex> lock(sinkMutex_);
623 Trace trace("MCHSink::Start");
624 #ifdef FEATURE_POWER_MANAGER
625 std::shared_ptr<PowerMgr::RunningLock> keepRunningLock;
626 if (runningLockManager_ == nullptr) {
627 WatchTimeout guard("PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock:Start");
628 keepRunningLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock("AudioMultiChannelBackgroundPlay",
629 PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_AUDIO);
630 guard.CheckCurrTimeout();
631 if (keepRunningLock) {
632 runningLockManager_ = std::make_shared<AudioRunningLockManager<PowerMgr::RunningLock>> (keepRunningLock);
633 }
634 }
635
636 if (runningLockManager_ != nullptr) {
637 AUDIO_INFO_LOG("keepRunningLock lock");
638 runningLockManager_->Lock(RUNNINGLOCK_LOCK_TIMEOUTMS_LASTING); // -1 for lasting.
639 } else {
640 AUDIO_WARNING_LOG("keepRunningLock is null, playback can not work well!");
641 }
642 #endif
643 dumpFileName_ = "multichannel_renderersink_" + GetTime() + "_" + std::to_string(attr_.sampleRate) + "_"
644 + std::to_string(attr_.channel) + "_" + std::to_string(attr_.format) + ".pcm";
645 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpFileName_, &dumpFile_);
646
647 if (!started_) {
648 int32_t ret = audioRender_->Start(audioRender_);
649 if (ret) {
650 AUDIO_ERR_LOG("Mch Start failed!");
651 return ERR_NOT_STARTED;
652 }
653 UpdateSinkState(true);
654 started_ = true;
655 CHECK_AND_RETURN_RET_LOG(CheckHdiFuncWhenStart() == SUCCESS, ERR_NOT_STARTED,
656 "Some Hdi function failed after starting");
657 }
658 AudioPerformanceMonitor::GetInstance().RecordTimeStamp(ADAPTER_TYPE_MULTICHANNEL, INIT_LASTWRITTEN_TIME);
659 return SUCCESS;
660 }
661
CheckHdiFuncWhenStart()662 int32_t MultiChannelRendererSinkInner::CheckHdiFuncWhenStart()
663 {
664 uint64_t frameSize = 0;
665 uint64_t frameCount = 0;
666 int32_t ret = audioRender_->GetFrameSize(audioRender_, &frameSize);
667 if (ret) {
668 AUDIO_ERR_LOG("Mch GetFrameSize failed!");
669 return ERR_NOT_STARTED;
670 }
671 ret = audioRender_->GetFrameCount(audioRender_, &frameCount);
672 if (ret) {
673 AUDIO_ERR_LOG("Mch GetFrameCount failed!");
674 return ERR_NOT_STARTED;
675 }
676 ret = audioRender_->SetVolume(audioRender_, 1);
677 if (ret) {
678 AUDIO_ERR_LOG("Mch setvolume failed!");
679 return ERR_NOT_STARTED;
680 }
681 return SUCCESS;
682 }
683
SetVolume(float left,float right)684 int32_t MultiChannelRendererSinkInner::SetVolume(float left, float right)
685 {
686 int32_t ret;
687 float volume;
688
689 if (audioRender_ == nullptr) {
690 AUDIO_ERR_LOG("SetVolume failed audioRender_ null");
691 return ERR_INVALID_HANDLE;
692 }
693
694 leftVolume_ = left;
695 rightVolume_ = right;
696 if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
697 volume = rightVolume_;
698 } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
699 volume = leftVolume_;
700 } else {
701 volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
702 }
703
704 ret = audioRender_->SetVolume(audioRender_, volume);
705 if (ret) {
706 AUDIO_ERR_LOG("Set volume failed!");
707 }
708
709 return ret;
710 }
711
GetVolume(float & left,float & right)712 int32_t MultiChannelRendererSinkInner::GetVolume(float &left, float &right)
713 {
714 left = leftVolume_;
715 right = rightVolume_;
716 return SUCCESS;
717 }
718
SetVoiceVolume(float volume)719 int32_t MultiChannelRendererSinkInner::SetVoiceVolume(float volume)
720 {
721 Trace trace("AudioRendererSinkInner::SetVoiceVolume");
722 if (audioAdapter_ == nullptr) {
723 AUDIO_ERR_LOG("SetVoiceVolume failed, audioAdapter_ is null");
724 return ERR_INVALID_HANDLE;
725 }
726 AUDIO_DEBUG_LOG("SetVoiceVolume %{public}f", volume);
727 return audioAdapter_->SetVoiceVolume(audioAdapter_, volume);
728 }
729
GetLatency(uint32_t * latency)730 int32_t MultiChannelRendererSinkInner::GetLatency(uint32_t *latency)
731 {
732 Trace trace("MultiChannelRendererSinkInner::GetLatency");
733 if (audioRender_ == nullptr) {
734 AUDIO_ERR_LOG("GetLatency failed audio render null");
735 return ERR_INVALID_HANDLE;
736 }
737
738 if (!latency) {
739 AUDIO_ERR_LOG("GetLatency failed latency null");
740 return ERR_INVALID_PARAM;
741 }
742
743 uint32_t hdiLatency;
744 if (audioRender_->GetLatency(audioRender_, &hdiLatency) == 0) {
745 *latency = hdiLatency;
746 return SUCCESS;
747 } else {
748 return ERR_OPERATION_FAILED;
749 }
750 }
751
GetAudioCategory(AudioScene audioScene)752 static AudioCategory GetAudioCategory(AudioScene audioScene)
753 {
754 AudioCategory audioCategory;
755 switch (audioScene) {
756 case AUDIO_SCENE_DEFAULT:
757 audioCategory = AUDIO_IN_MEDIA;
758 break;
759 case AUDIO_SCENE_RINGING:
760 case AUDIO_SCENE_VOICE_RINGING:
761 audioCategory = AUDIO_IN_RINGTONE;
762 break;
763 case AUDIO_SCENE_PHONE_CALL:
764 audioCategory = AUDIO_IN_CALL;
765 break;
766 case AUDIO_SCENE_PHONE_CHAT:
767 audioCategory = AUDIO_IN_COMMUNICATION;
768 break;
769 default:
770 audioCategory = AUDIO_IN_MEDIA;
771 break;
772 }
773 AUDIO_DEBUG_LOG("Audio category returned is: %{public}d", audioCategory);
774
775 return audioCategory;
776 }
777
SetOutputPortPin(DeviceType outputDevice,AudioRouteNode & sink)778 static int32_t SetOutputPortPin(DeviceType outputDevice, AudioRouteNode &sink)
779 {
780 int32_t ret = SUCCESS;
781 switch (outputDevice) {
782 case DEVICE_TYPE_EARPIECE:
783 sink.ext.device.type = PIN_OUT_EARPIECE;
784 sink.ext.device.desc = (char *)"pin_out_earpiece";
785 break;
786 case DEVICE_TYPE_SPEAKER:
787 sink.ext.device.type = PIN_OUT_SPEAKER;
788 sink.ext.device.desc = (char *)"pin_out_speaker";
789 break;
790 case DEVICE_TYPE_WIRED_HEADSET:
791 sink.ext.device.type = PIN_OUT_HEADSET;
792 sink.ext.device.desc = (char *)"pin_out_headset";
793 break;
794 case DEVICE_TYPE_USB_ARM_HEADSET:
795 sink.ext.device.type = PIN_OUT_USB_HEADSET;
796 sink.ext.device.desc = (char *)"pin_out_usb_headset";
797 break;
798 case DEVICE_TYPE_USB_HEADSET:
799 sink.ext.device.type = PIN_OUT_USB_EXT;
800 sink.ext.device.desc = (char *)"pin_out_usb_ext";
801 break;
802 case DEVICE_TYPE_BLUETOOTH_SCO:
803 sink.ext.device.type = PIN_OUT_BLUETOOTH_SCO;
804 sink.ext.device.desc = (char *)"pin_out_bluetooth_sco";
805 break;
806 case DEVICE_TYPE_BLUETOOTH_A2DP:
807 sink.ext.device.type = PIN_OUT_BLUETOOTH_A2DP;
808 sink.ext.device.desc = (char *)"pin_out_bluetooth_a2dp";
809 break;
810 default:
811 ret = ERR_NOT_SUPPORTED;
812 break;
813 }
814
815 return ret;
816 }
817
SetOutputRoutes(std::vector<DeviceType> & outputDevices)818 int32_t MultiChannelRendererSinkInner::SetOutputRoutes(std::vector<DeviceType> &outputDevices)
819 {
820 CHECK_AND_RETURN_RET_LOG(!outputDevices.empty() && outputDevices.size() <= AUDIO_CONCURRENT_ACTIVE_DEVICES_LIMIT,
821 ERR_INVALID_PARAM, "Invalid audio devices.");
822 DeviceType outputDevice = outputDevices.front();
823 AudioPortPin outputPortPin = PIN_OUT_SPEAKER;
824 return SetOutputRoute(outputDevice, outputPortPin);
825 }
826
SetOutputRoute(DeviceType outputDevice,AudioPortPin & outputPortPin)827 int32_t MultiChannelRendererSinkInner::SetOutputRoute(DeviceType outputDevice, AudioPortPin &outputPortPin)
828 {
829 if (outputDevice == currentActiveDevice_) {
830 AUDIO_INFO_LOG("SetOutputRoute output device not change");
831 return SUCCESS;
832 }
833 currentActiveDevice_ = outputDevice;
834
835 AudioRouteNode source = {};
836 AudioRouteNode sink = {};
837
838 int32_t ret = SetOutputPortPin(outputDevice, sink);
839 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "SetOutputRoute FAILED: %{public}d", ret);
840
841 outputPortPin = sink.ext.device.type;
842 AUDIO_INFO_LOG("Output PIN is: 0x%{public}X", outputPortPin);
843
844 InitAudioRouteNode(source, sink);
845
846 AudioRoute route = {
847 .sources = &source,
848 .sourcesLen = 1,
849 .sinks = &sink,
850 .sinksLen = 1,
851 };
852
853 renderEmptyFrameCount_ = 5; // preRender 5 frames
854 std::unique_lock<std::mutex> lock(switchMutex_);
855 switchCV_.wait_for(lock, std::chrono::milliseconds(SLEEP_TIME_FOR_RENDER_EMPTY), [this] {
856 if (renderEmptyFrameCount_ == 0) {
857 AUDIO_INFO_LOG("Wait for preRender end.");
858 return true;
859 }
860 AUDIO_DEBUG_LOG("Current renderEmptyFrameCount_ is %{public}d", renderEmptyFrameCount_.load());
861 return false;
862 });
863 int64_t stamp = ClockTime::GetCurNano();
864 CHECK_AND_RETURN_RET_LOG(audioAdapter_ != nullptr, ERR_INVALID_HANDLE, "SetOutputRoute failed with null adapter");
865 inSwitch_.store(true);
866 ret = audioAdapter_->UpdateAudioRoute(audioAdapter_, &route, &routeHandle_);
867 inSwitch_.store(false);
868 stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
869 AUDIO_INFO_LOG("UpdateAudioRoute cost[%{public}" PRId64 "]ms", stamp);
870 renderEmptyFrameCount_ = 5; // render 5 empty frame
871 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "UpdateAudioRoute failed");
872
873 return SUCCESS;
874 }
875
InitAudioRouteNode(AudioRouteNode & source,AudioRouteNode & sink)876 void MultiChannelRendererSinkInner::InitAudioRouteNode(AudioRouteNode &source, AudioRouteNode &sink)
877 {
878 source.portId = 0;
879 source.role = AUDIO_PORT_SOURCE_ROLE;
880 source.type = AUDIO_PORT_MIX_TYPE;
881 source.ext.mix.moduleId = 0;
882 source.ext.mix.streamId = static_cast<int32_t>(
883 GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_MULTICHANNEL));
884 source.ext.device.desc = (char *)"";
885
886 sink.portId = static_cast<int32_t>(audioPort_.portId);
887 sink.role = AUDIO_PORT_SINK_ROLE;
888 sink.type = AUDIO_PORT_DEVICE_TYPE;
889 sink.ext.device.moduleId = 0;
890 sink.ext.device.desc = (char *)"";
891 }
892
GetAudioScene()893 int32_t MultiChannelRendererSinkInner::GetAudioScene()
894 {
895 return currentAudioScene_;
896 }
897
SetAudioScene(AudioScene audioScene,std::vector<DeviceType> & activeDevices)898 int32_t MultiChannelRendererSinkInner::SetAudioScene(AudioScene audioScene, std::vector<DeviceType> &activeDevices)
899 {
900 CHECK_AND_RETURN_RET_LOG(!activeDevices.empty() && activeDevices.size() <= AUDIO_CONCURRENT_ACTIVE_DEVICES_LIMIT,
901 ERR_INVALID_PARAM, "Invalid audio devices.");
902 DeviceType activeDevice = activeDevices.front();
903 AUDIO_INFO_LOG("SetAudioScene scene: %{public}d, device: %{public}d", audioScene, activeDevice);
904 CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene < AUDIO_SCENE_MAX,
905 ERR_INVALID_PARAM, "invalid audioScene");
906 if (audioRender_ == nullptr) {
907 AUDIO_ERR_LOG("SetAudioScene failed audio render handle is null!");
908 return ERR_INVALID_HANDLE;
909 }
910 if (openSpeaker_) {
911 AudioPortPin audioSceneOutPort = PIN_OUT_SPEAKER;
912 if (halName_ == "usb") {
913 audioSceneOutPort = PIN_OUT_USB_HEADSET;
914 }
915
916 AUDIO_DEBUG_LOG("OUTPUT port is %{public}d", audioSceneOutPort);
917 int32_t ret = SUCCESS;
918 if (audioScene != currentAudioScene_) {
919 struct AudioSceneDescriptor scene;
920 scene.scene.id = GetAudioCategory(audioScene);
921 scene.desc.pins = audioSceneOutPort;
922 scene.desc.desc = (char *)"";
923
924 ret = audioRender_->SelectScene(audioRender_, &scene);
925 if (ret < 0) {
926 AUDIO_ERR_LOG("Select scene FAILED: %{public}d", ret);
927 return ERR_OPERATION_FAILED;
928 }
929 currentAudioScene_ = audioScene;
930 }
931
932 ret = SetOutputRoute(activeDevice, audioSceneOutPort);
933 if (ret < 0) {
934 AUDIO_ERR_LOG("Update route FAILED: %{public}d", ret);
935 }
936 }
937 return SUCCESS;
938 }
939
GetTransactionId(uint64_t * transactionId)940 int32_t MultiChannelRendererSinkInner::GetTransactionId(uint64_t *transactionId)
941 {
942 AUDIO_INFO_LOG("MultiChannelRendererSinkInner::GetTransactionId");
943
944 if (audioRender_ == nullptr) {
945 AUDIO_ERR_LOG("GetTransactionId failed audio render null");
946 return ERR_INVALID_HANDLE;
947 }
948
949 if (!transactionId) {
950 AUDIO_ERR_LOG("GetTransactionId failed transactionId null");
951 return ERR_INVALID_PARAM;
952 }
953
954 *transactionId = reinterpret_cast<uint64_t>(audioRender_);
955 return SUCCESS;
956 }
957
Stop(void)958 int32_t MultiChannelRendererSinkInner::Stop(void)
959 {
960 std::lock_guard<std::mutex> lock(sinkMutex_);
961 Trace trace("MCHSink::Stop");
962 AUDIO_INFO_LOG("Stop.");
963 #ifdef FEATURE_POWER_MANAGER
964 if (runningLockManager_ != nullptr) {
965 AUDIO_INFO_LOG("keepRunningLock unLock");
966 runningLockManager_->UnLock();
967 } else {
968 AUDIO_WARNING_LOG("keepRunningLock is null, playback can not work well!");
969 }
970 #endif
971
972 if (audioRender_ == nullptr) {
973 AUDIO_ERR_LOG("Stop failed audioRender_ null");
974 return ERR_INVALID_HANDLE;
975 }
976
977 if (started_) {
978 int32_t ret = audioRender_->Stop(audioRender_);
979 UpdateSinkState(false);
980 if (!ret) {
981 started_ = false;
982 return SUCCESS;
983 } else {
984 AUDIO_ERR_LOG("Stop failed!");
985 return ERR_OPERATION_FAILED;
986 }
987 }
988
989 return SUCCESS;
990 }
991
Pause(void)992 int32_t MultiChannelRendererSinkInner::Pause(void)
993 {
994 std::lock_guard<std::mutex> lock(sinkMutex_);
995 Trace trace("MCHSink::Pause");
996 if (audioRender_ == nullptr) {
997 AUDIO_ERR_LOG("Pause failed audioRender_ null");
998 return ERR_INVALID_HANDLE;
999 }
1000
1001 if (!started_) {
1002 AUDIO_ERR_LOG("Pause invalid state!");
1003 return ERR_OPERATION_FAILED;
1004 }
1005
1006 if (!paused_) {
1007 int32_t ret = audioRender_->Pause(audioRender_);
1008 if (!ret) {
1009 paused_ = true;
1010 return SUCCESS;
1011 } else {
1012 AUDIO_ERR_LOG("Pause failed!");
1013 return ERR_OPERATION_FAILED;
1014 }
1015 }
1016
1017 return SUCCESS;
1018 }
1019
Resume(void)1020 int32_t MultiChannelRendererSinkInner::Resume(void)
1021 {
1022 std::lock_guard<std::mutex> lock(sinkMutex_);
1023 if (audioRender_ == nullptr) {
1024 AUDIO_ERR_LOG("Resume failed audioRender_ null");
1025 return ERR_INVALID_HANDLE;
1026 }
1027
1028 if (!started_) {
1029 AUDIO_ERR_LOG("Resume invalid state!");
1030 return ERR_OPERATION_FAILED;
1031 }
1032
1033 if (paused_) {
1034 int32_t ret = audioRender_->Resume(audioRender_);
1035 if (!ret) {
1036 paused_ = false;
1037 return SUCCESS;
1038 } else {
1039 AUDIO_ERR_LOG("Resume failed!");
1040 return ERR_OPERATION_FAILED;
1041 }
1042 }
1043 AudioPerformanceMonitor::GetInstance().RecordTimeStamp(ADAPTER_TYPE_MULTICHANNEL, INIT_LASTWRITTEN_TIME);
1044 return SUCCESS;
1045 }
1046
Reset(void)1047 int32_t MultiChannelRendererSinkInner::Reset(void)
1048 {
1049 if (started_ && audioRender_ != nullptr) {
1050 int32_t ret = audioRender_->Flush(audioRender_);
1051 if (!ret) {
1052 return SUCCESS;
1053 } else {
1054 AUDIO_ERR_LOG("Reset failed!");
1055 return ERR_OPERATION_FAILED;
1056 }
1057 }
1058
1059 return ERR_OPERATION_FAILED;
1060 }
1061
Flush(void)1062 int32_t MultiChannelRendererSinkInner::Flush(void)
1063 {
1064 Trace trace("MCHSink::Flush");
1065 if (started_ && audioRender_ != nullptr) {
1066 int32_t ret = audioRender_->Flush(audioRender_);
1067 if (!ret) {
1068 return SUCCESS;
1069 } else {
1070 AUDIO_ERR_LOG("Flush failed!");
1071 return ERR_OPERATION_FAILED;
1072 }
1073 }
1074
1075 return ERR_OPERATION_FAILED;
1076 }
1077
SuspendRenderSink(void)1078 int32_t MultiChannelRendererSinkInner::SuspendRenderSink(void)
1079 {
1080 return SUCCESS;
1081 }
1082
RestoreRenderSink(void)1083 int32_t MultiChannelRendererSinkInner::RestoreRenderSink(void)
1084 {
1085 return SUCCESS;
1086 }
1087
Preload(const std::string & usbInfoStr)1088 int32_t MultiChannelRendererSinkInner::Preload(const std::string &usbInfoStr)
1089 {
1090 CHECK_AND_RETURN_RET_LOG(halName_ == "usb", ERR_INVALID_OPERATION, "Preload only supported for usb");
1091
1092 int32_t ret = UpdateUsbAttrs(usbInfoStr);
1093 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Preload failed when init attr");
1094
1095 ret = InitAdapter();
1096 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Preload failed when init adapter");
1097
1098 ret = InitRender();
1099 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Preload failed when init render");
1100
1101 return SUCCESS;
1102 }
1103
ParseAudioFormat(const std::string & format)1104 static HdiAdapterFormat ParseAudioFormat(const std::string &format)
1105 {
1106 if (format == "AUDIO_FORMAT_PCM_16_BIT") {
1107 return HdiAdapterFormat::SAMPLE_S16;
1108 } else if (format == "AUDIO_FORMAT_PCM_24_BIT" || format == "AUDIO_FORMAT_PCM_24_BIT_PACKED") {
1109 return HdiAdapterFormat::SAMPLE_S24;
1110 } else if (format == "AUDIO_FORMAT_PCM_32_BIT") {
1111 return HdiAdapterFormat::SAMPLE_S32;
1112 } else {
1113 return HdiAdapterFormat::SAMPLE_S16;
1114 }
1115 }
1116
UpdateUsbAttrs(const std::string & usbInfoStr)1117 int32_t MultiChannelRendererSinkInner::UpdateUsbAttrs(const std::string &usbInfoStr)
1118 {
1119 CHECK_AND_RETURN_RET_LOG(usbInfoStr != "", ERR_INVALID_PARAM, "usb info string error");
1120
1121 auto sinkRate_begin = usbInfoStr.find("sink_rate:");
1122 auto sinkRate_end = usbInfoStr.find_first_of(";", sinkRate_begin);
1123 std::string sampleRateStr = usbInfoStr.substr(sinkRate_begin + std::strlen("sink_rate:"),
1124 sinkRate_end - sinkRate_begin - std::strlen("sink_rate:"));
1125 auto sinkFormat_begin = usbInfoStr.find("sink_format:");
1126 auto sinkFormat_end = usbInfoStr.find_first_of(";", sinkFormat_begin);
1127 std::string formatStr = usbInfoStr.substr(sinkFormat_begin + std::strlen("sink_format:"),
1128 sinkFormat_end - sinkFormat_begin - std::strlen("sink_format:"));
1129
1130 // usb default config
1131 CHECK_AND_RETURN_RET_LOG(StringConverter(sampleRateStr, attr_.sampleRate), ERR_INVALID_PARAM,
1132 "convert invalid sampleRate: %{public}s", sampleRateStr.c_str());
1133 attr_.channel = STEREO_CHANNEL_COUNT;
1134 attr_.format = ParseAudioFormat(formatStr);
1135
1136 adapterNameCase_ = "usb";
1137 openSpeaker_ = 0;
1138
1139 return SUCCESS;
1140 }
1141
InitAdapter()1142 int32_t MultiChannelRendererSinkInner::InitAdapter()
1143 {
1144 AUDIO_INFO_LOG("MultiChannelRendererSinkInner::InitAdapter");
1145
1146 if (adapterInited_) {
1147 AUDIO_INFO_LOG("Adapter already inited");
1148 return SUCCESS;
1149 }
1150
1151 if (InitAudioManager() != 0) {
1152 AUDIO_ERR_LOG("Init audio manager Fail.");
1153 return ERR_NOT_STARTED;
1154 }
1155
1156 AudioAdapterDescriptor descs[MAX_AUDIO_ADAPTER_NUM];
1157 uint32_t size = MAX_AUDIO_ADAPTER_NUM;
1158 if (audioManager_ == nullptr) {
1159 AUDIO_ERR_LOG("The audioManager is nullptr.");
1160 return ERROR;
1161 }
1162 int32_t ret = audioManager_->GetAllAdapters(audioManager_, (struct AudioAdapterDescriptor *)&descs, &size);
1163 if (size > MAX_AUDIO_ADAPTER_NUM || size == 0 || ret != 0) {
1164 AUDIO_ERR_LOG("Get adapters failed");
1165 return ERR_NOT_STARTED;
1166 }
1167
1168 enum AudioPortDirection port = PORT_OUT;
1169 int32_t index =
1170 SwitchAdapterRender((struct AudioAdapterDescriptor *)&descs, "primary", port, audioPort_, size);
1171 CHECK_AND_RETURN_RET_LOG((index >= 0), ERR_NOT_STARTED, "Switch Adapter failed");
1172
1173 adapterDesc_ = descs[index];
1174 CHECK_AND_RETURN_RET_LOG((audioManager_->LoadAdapter(audioManager_, &adapterDesc_, &audioAdapter_) == SUCCESS),
1175 ERR_NOT_STARTED, "Load Adapter Fail.");
1176
1177 adapterInited_ = true;
1178
1179 return SUCCESS;
1180 }
1181
InitRender()1182 int32_t MultiChannelRendererSinkInner::InitRender()
1183 {
1184 AUDIO_INFO_LOG("MultiChannelRendererSinkInner::InitRender");
1185
1186 if (renderInited_) {
1187 AUDIO_INFO_LOG("Render already inited");
1188 return SUCCESS;
1189 }
1190
1191 CHECK_AND_RETURN_RET_LOG((audioAdapter_ != nullptr), ERR_NOT_STARTED, "Audio device not loaded");
1192
1193 // Initialization port information, can fill through mode and other parameters
1194 CHECK_AND_RETURN_RET_LOG((audioAdapter_->InitAllPorts(audioAdapter_) == SUCCESS),
1195 ERR_NOT_STARTED, "Init ports failed");
1196
1197 if (CreateRender(audioPort_) != 0) {
1198 AUDIO_ERR_LOG("Create render failed, Audio Port: %{public}d", audioPort_.portId);
1199 return ERR_NOT_STARTED;
1200 }
1201
1202 renderInited_ = true;
1203
1204 return SUCCESS;
1205 }
1206
ResetOutputRouteForDisconnect(DeviceType device)1207 void MultiChannelRendererSinkInner::ResetOutputRouteForDisconnect(DeviceType device)
1208 {
1209 if (currentActiveDevice_ == device) {
1210 currentActiveDevice_ = DEVICE_TYPE_NONE;
1211 }
1212 }
1213
SetPaPower(int32_t flag)1214 int32_t MultiChannelRendererSinkInner::SetPaPower(int32_t flag)
1215 {
1216 (void)flag;
1217 return ERR_NOT_SUPPORTED;
1218 }
1219
SetPriPaPower()1220 int32_t MultiChannelRendererSinkInner::SetPriPaPower()
1221 {
1222 return ERR_NOT_SUPPORTED;
1223 }
1224
UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],const size_t size)1225 int32_t MultiChannelRendererSinkInner::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size)
1226 {
1227 #ifdef FEATURE_POWER_MANAGER
1228 if (!runningLockManager_) {
1229 return ERROR;
1230 }
1231
1232 return runningLockManager_->UpdateAppsUid(appsUid, appsUid + size);
1233 #endif
1234
1235 return SUCCESS;
1236 }
1237
UpdateAppsUid(const std::vector<int32_t> & appsUid)1238 int32_t MultiChannelRendererSinkInner::UpdateAppsUid(const std::vector<int32_t> &appsUid)
1239 {
1240 AUDIO_WARNING_LOG("not supported.");
1241 return SUCCESS;
1242 }
1243
1244 // UpdateSinkState must be called with MultiChannelRendererSinkInner::sinkMutex_ held
UpdateSinkState(bool started)1245 void MultiChannelRendererSinkInner::UpdateSinkState(bool started)
1246 {
1247 if (callback_) {
1248 callback_->OnAudioSinkStateChange(sinkId_, started);
1249 } else {
1250 AUDIO_WARNING_LOG("AudioSinkCallback is nullptr");
1251 }
1252 }
1253
GetRenderId(uint32_t & renderId) const1254 int32_t MultiChannelRendererSinkInner::GetRenderId(uint32_t &renderId) const
1255 {
1256 renderId = GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_MULTICHANNEL);
1257 return SUCCESS;
1258 }
1259
DumpData(std::string fileName,void * buffer,size_t len)1260 void MultiChannelRendererSinkInner::DumpData(std::string fileName, void *buffer, size_t len)
1261 {
1262 if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
1263 AudioCacheMgr::GetInstance().CacheData(fileName, buffer, len);
1264 }
1265 }
1266
1267 // LCOV_EXCL_STOP
1268 } // namespace AudioStandard
1269 } // namespace OHOS
1270