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