• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param, &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