• 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 "bluetooth_renderer_sink.h"
17 
18 #include <cstdio>
19 #include <cstring>
20 #include <string>
21 #include <list>
22 #include <cinttypes>
23 
24 #include <dlfcn.h>
25 #include <unistd.h>
26 
27 #include "audio_proxy_manager.h"
28 #include "running_lock.h"
29 #include "power_mgr_client.h"
30 
31 #include "audio_errors.h"
32 #include "audio_log.h"
33 #include "audio_utils.h"
34 
35 using namespace std;
36 using namespace OHOS::HDI::Audio_Bluetooth;
37 
38 namespace OHOS {
39 namespace AudioStandard {
40 namespace {
41 const int32_t HALF_FACTOR = 2;
42 const int32_t MAX_AUDIO_ADAPTER_NUM = 5;
43 const int32_t RENDER_FRAME_NUM = -4;
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 RENDER_FRAME_INTERVAL_IN_MICROSECONDS = 10000;
49 const uint32_t INT_32_MAX = 0x7fffffff;
50 const uint32_t PCM_8_BIT = 8;
51 const uint32_t PCM_16_BIT = 16;
52 const uint32_t PCM_24_BIT = 24;
53 const uint32_t PCM_32_BIT = 32;
54 const uint32_t STEREO_CHANNEL_COUNT = 2;
55 constexpr int32_t RUNNINGLOCK_LOCK_TIMEOUTMS_LASTING = -1;
56 constexpr uint32_t BIT_TO_BYTES = 8;
57 }
58 
59 #ifdef BT_DUMPFILE
60 const char *g_audioOutTestFilePath = "/data/data/.pulse_dir/dump_audiosink.pcm";
61 #endif // BT_DUMPFILE
62 
63 typedef struct {
64     HDI::Audio_Bluetooth::AudioFormat format;
65     uint32_t sampleFmt;
66     uint32_t sampleRate;
67     uint32_t channel;
68     float volume;
69 } BluetoothSinkAttr;
70 
71 class BluetoothRendererSinkInner : public BluetoothRendererSink {
72 public:
73     int32_t Init(IAudioSinkAttr attr) override;
74     bool IsInited(void) override;
75     void DeInit(void) override;
76     int32_t Start(void) override;
77     int32_t Stop(void) override;
78     int32_t Flush(void) override;
79     int32_t Reset(void) override;
80     int32_t Pause(void) override;
81     int32_t Resume(void) override;
82     int32_t RenderFrame(char &data, uint64_t len, uint64_t &writeLen) override;
83     int32_t SetVolume(float left, float right) override;
84     int32_t GetVolume(float &left, float &right) override;
85     int32_t GetLatency(uint32_t *latency) override;
86     int32_t GetTransactionId(uint64_t *transactionId) override;
87     void SetAudioMonoState(bool audioMono) override;
88     void SetAudioBalanceValue(float audioBalance) override;
89 
90     int32_t SetVoiceVolume(float volume) override;
91     int32_t SetAudioScene(AudioScene audioScene, DeviceType activeDevice) override;
92     int32_t SetOutputRoute(DeviceType deviceType) override;
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 RegisterParameterCallback(IAudioSinkCallback* callback) override;
96 
97     bool GetAudioMonoState();
98     float GetAudioBalanceValue();
99 
100     BluetoothRendererSinkInner();
101     ~BluetoothRendererSinkInner();
102 private:
103     BluetoothSinkAttr attr_;
104     bool rendererInited_;
105     bool started_;
106     bool isFirstWrite_ = true;
107     bool paused_;
108     float leftVolume_;
109     float rightVolume_;
110     struct HDI::Audio_Bluetooth::AudioProxyManager *audioManager_;
111     struct HDI::Audio_Bluetooth::AudioAdapter *audioAdapter_;
112     struct HDI::Audio_Bluetooth::AudioRender *audioRender_;
113     struct HDI::Audio_Bluetooth::AudioPort audioPort = {};
114     void *handle_;
115     bool audioMonoState_ = false;
116     bool audioBalanceState_ = false;
117     float leftBalanceCoef_ = 1.0f;
118     float rightBalanceCoef_ = 1.0f;
119     int64_t lastCallWriteTime_ = 0;
120 
121     std::shared_ptr<PowerMgr::RunningLock> keepRunningLock_;
122 
123     int32_t CreateRender(struct HDI::Audio_Bluetooth::AudioPort &renderPort);
124     int32_t InitAudioManager();
125     void AdjustStereoToMono(char *data, uint64_t len);
126     void AdjustAudioBalance(char *data, uint64_t len);
127     AudioFormat ConverToHdiFormat(AudioSampleFormat format);
128     int64_t BytesToNanoTime(size_t lens);
129 #ifdef BT_DUMPFILE
130     FILE *pfd;
131 #endif // DUMPFILE
132 };
133 
BluetoothRendererSinkInner()134 BluetoothRendererSinkInner::BluetoothRendererSinkInner()
135     : rendererInited_(false), started_(false), paused_(false), leftVolume_(DEFAULT_VOLUME_LEVEL),
136       rightVolume_(DEFAULT_VOLUME_LEVEL), audioManager_(nullptr), audioAdapter_(nullptr),
137       audioRender_(nullptr), handle_(nullptr)
138 {
139     attr_ = {};
140 #ifdef BT_DUMPFILE
141     pfd = nullptr;
142 #endif // BT_DUMPFILE
143 }
144 
~BluetoothRendererSinkInner()145 BluetoothRendererSinkInner::~BluetoothRendererSinkInner()
146 {
147     BluetoothRendererSinkInner::DeInit();
148 }
149 
GetInstance()150 BluetoothRendererSink *BluetoothRendererSink::GetInstance()
151 {
152     static BluetoothRendererSinkInner audioRenderer;
153 
154     return &audioRenderer;
155 }
156 
IsInited(void)157 bool BluetoothRendererSinkInner::IsInited(void)
158 {
159     return rendererInited_;
160 }
161 
SetVoiceVolume(float volume)162 int32_t BluetoothRendererSinkInner::SetVoiceVolume(float volume)
163 {
164     return ERR_NOT_SUPPORTED;
165 }
166 
SetAudioScene(AudioScene audioScene,DeviceType activeDevice)167 int32_t BluetoothRendererSinkInner::SetAudioScene(AudioScene audioScene, DeviceType activeDevice)
168 {
169     return ERR_NOT_SUPPORTED;
170 }
171 
SetOutputRoute(DeviceType deviceType)172 int32_t BluetoothRendererSinkInner::SetOutputRoute(DeviceType deviceType)
173 {
174     return ERR_NOT_SUPPORTED;
175 }
176 
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)177 void BluetoothRendererSinkInner::SetAudioParameter(const AudioParamKey key, const std::string& condition,
178     const std::string& value)
179 {
180     AUDIO_INFO_LOG("SetAudioParameter: key %{public}d, condition: %{public}s, value: %{public}s", key,
181         condition.c_str(), value.c_str());
182     if (audioRender_ == nullptr) {
183         AUDIO_ERR_LOG("SetAudioParameter for render failed, audioRender_ is null");
184         return;
185     } else {
186         int32_t ret = audioRender_->attr.SetExtraParams(reinterpret_cast<AudioHandle>(audioRender_), value.c_str());
187         if (ret != SUCCESS) {
188             AUDIO_ERR_LOG("SetAudioParameter for render failed, error code: %d", ret);
189         }
190     }
191 }
192 
GetAudioParameter(const AudioParamKey key,const std::string & condition)193 std::string BluetoothRendererSinkInner::GetAudioParameter(const AudioParamKey key, const std::string& condition)
194 {
195     AUDIO_ERR_LOG("BluetoothRendererSink GetAudioParameter not supported.");
196     return "";
197 }
198 
RegisterParameterCallback(IAudioSinkCallback * callback)199 void BluetoothRendererSinkInner::RegisterParameterCallback(IAudioSinkCallback* callback)
200 {
201     AUDIO_ERR_LOG("BluetoothRendererSink RegisterParameterCallback not supported.");
202 }
203 
DeInit()204 void BluetoothRendererSinkInner::DeInit()
205 {
206     AUDIO_INFO_LOG("DeInit.");
207     started_ = false;
208     rendererInited_ = false;
209     if ((audioRender_ != nullptr) && (audioAdapter_ != nullptr)) {
210         audioAdapter_->DestroyRender(audioAdapter_, audioRender_);
211     }
212     audioRender_ = nullptr;
213 
214     if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
215         audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
216     }
217     audioAdapter_ = nullptr;
218     audioManager_ = nullptr;
219 
220     if (handle_ != nullptr) {
221         dlclose(handle_);
222         handle_ = nullptr;
223     }
224 
225 #ifdef BT_DUMPFILE
226     if (pfd) {
227         fclose(pfd);
228         pfd = nullptr;
229     }
230 #endif // BT_DUMPFILE
231 }
232 
InitAttrs(struct AudioSampleAttributes & attrs)233 void InitAttrs(struct AudioSampleAttributes &attrs)
234 {
235     /* Initialization of audio parameters for playback */
236     attrs.format = AUDIO_FORMAT_TYPE_PCM_16_BIT;
237     attrs.channelCount = AUDIO_CHANNELCOUNT;
238     attrs.frameSize = PCM_16_BIT * attrs.channelCount / PCM_8_BIT;
239     attrs.sampleRate = AUDIO_SAMPLE_RATE_48K;
240     attrs.interleaved = 0;
241     attrs.type = AUDIO_IN_MEDIA;
242     attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
243     attrs.isBigEndian = false;
244     attrs.isSignedData = true;
245     attrs.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (attrs.frameSize);
246     attrs.stopThreshold = INT_32_MAX;
247     attrs.silenceThreshold = 0;
248 }
249 
SwitchAdapter(struct AudioAdapterDescriptor * descs,string adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort & renderPort,int32_t size)250 static int32_t SwitchAdapter(struct AudioAdapterDescriptor *descs, string adapterNameCase,
251     enum AudioPortDirection portFlag, struct AudioPort &renderPort, int32_t size)
252 {
253     AUDIO_INFO_LOG("SwitchAdapter: adapterNameCase: %{public}s", adapterNameCase.c_str());
254     if (descs == nullptr) {
255         return ERROR;
256     }
257 
258     for (int32_t index = 0; index < size; index++) {
259         struct AudioAdapterDescriptor *desc = &descs[index];
260         if (desc == nullptr) {
261             continue;
262         }
263         AUDIO_DEBUG_LOG("SwitchAdapter: adapter name for %{public}d: %{public}s", index, desc->adapterName);
264         if (!strcmp(desc->adapterName, adapterNameCase.c_str())) {
265             for (uint32_t port = 0; port < desc->portNum; port++) {
266                 // Only find out the port of out in the sound card
267                 if (desc->ports[port].dir == portFlag) {
268                     renderPort = desc->ports[port];
269                     AUDIO_DEBUG_LOG("SwitchAdapter: index found %{public}d", index);
270                     return index;
271                 }
272             }
273         }
274     }
275     AUDIO_ERR_LOG("SwitchAdapter Fail");
276 
277     return ERR_INVALID_INDEX;
278 }
279 
InitAudioManager()280 int32_t BluetoothRendererSinkInner::InitAudioManager()
281 {
282     AUDIO_INFO_LOG("InitAudioManager: Initialize audio proxy manager");
283 
284 #ifdef __aarch64__
285     char resolvedPath[100] = "/vendor/lib64/chipsetsdk/libaudio_bluetooth_hdi_proxy_server.z.so";
286 #else
287     char resolvedPath[100] = "/vendor/lib/chipsetsdk/libaudio_bluetooth_hdi_proxy_server.z.so";
288 #endif
289     struct AudioProxyManager *(*getAudioManager)() = nullptr;
290 
291     handle_ = dlopen(resolvedPath, 1);
292     if (handle_ == nullptr) {
293         AUDIO_ERR_LOG("Open so Fail");
294         return ERR_INVALID_HANDLE;
295     }
296     AUDIO_DEBUG_LOG("dlopen successful");
297 
298     getAudioManager = (struct AudioProxyManager *(*)())(dlsym(handle_, "GetAudioProxyManagerFuncs"));
299     if (getAudioManager == nullptr) {
300         return ERR_INVALID_HANDLE;
301     }
302     AUDIO_DEBUG_LOG("getaudiomanager done");
303 
304     audioManager_ = getAudioManager();
305     if (audioManager_ == nullptr) {
306         return ERR_INVALID_HANDLE;
307     }
308     AUDIO_DEBUG_LOG("audio manager created");
309 
310     return 0;
311 }
312 
PcmFormatToBits(AudioFormat format)313 uint32_t PcmFormatToBits(AudioFormat format)
314 {
315     switch (format) {
316         case AUDIO_FORMAT_TYPE_PCM_8_BIT:
317             return PCM_8_BIT;
318         case AUDIO_FORMAT_TYPE_PCM_16_BIT:
319             return PCM_16_BIT;
320         case AUDIO_FORMAT_TYPE_PCM_24_BIT:
321             return PCM_24_BIT;
322         case AUDIO_FORMAT_TYPE_PCM_32_BIT:
323             return PCM_32_BIT;
324         default:
325             return PCM_24_BIT;
326     };
327 }
328 
CreateRender(struct AudioPort & renderPort)329 int32_t BluetoothRendererSinkInner::CreateRender(struct AudioPort &renderPort)
330 {
331     AUDIO_DEBUG_LOG("Create render in");
332     int32_t ret;
333     struct AudioSampleAttributes param;
334     InitAttrs(param);
335     param.sampleRate = attr_.sampleRate;
336     param.channelCount = attr_.channel;
337     param.format = attr_.format;
338     param.frameSize = PcmFormatToBits(param.format) * param.channelCount / PCM_8_BIT;
339     param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
340     AUDIO_DEBUG_LOG("BluetoothRendererSink Create render format: %{public}d", param.format);
341     struct AudioDeviceDescriptor deviceDesc;
342     deviceDesc.portId = renderPort.portId;
343     deviceDesc.pins = PIN_OUT_SPEAKER;
344     deviceDesc.desc = nullptr;
345     ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, &param, &audioRender_);
346     if (ret != 0 || audioRender_ == nullptr) {
347         AUDIO_ERR_LOG("AudioDeviceCreateRender failed");
348         audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
349         return ERR_NOT_STARTED;
350     }
351     AUDIO_DEBUG_LOG("create render done");
352 
353     return 0;
354 }
355 
ConverToHdiFormat(AudioSampleFormat format)356 AudioFormat BluetoothRendererSinkInner::ConverToHdiFormat(AudioSampleFormat format)
357 {
358     AudioFormat hdiFormat;
359     switch (format) {
360         case SAMPLE_U8:
361             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
362             break;
363         case SAMPLE_S16LE:
364             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
365             break;
366         case SAMPLE_S24LE:
367             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
368             break;
369         case SAMPLE_S32LE:
370             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
371             break;
372         default:
373             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
374             break;
375     }
376 
377     return hdiFormat;
378 }
379 
Init(IAudioSinkAttr attr)380 int32_t BluetoothRendererSinkInner::Init(IAudioSinkAttr attr)
381 {
382     AUDIO_INFO_LOG("Init: %{public}d", attr.format);
383 
384     attr_.format = ConverToHdiFormat(attr.format);
385     attr_.sampleFmt = attr.sampleFmt;
386     attr_.sampleRate = attr.sampleRate;
387     attr_.channel = attr.channel;
388     attr_.volume = attr.volume;
389 
390     string adapterNameCase = "bt_a2dp";  // Set sound card information
391     enum AudioPortDirection port = PORT_OUT; // Set port information
392 
393     if (InitAudioManager() != 0) {
394         AUDIO_ERR_LOG("Init audio manager Fail");
395         return ERR_NOT_STARTED;
396     }
397 
398     int32_t size = 0;
399     struct AudioAdapterDescriptor *descs = nullptr;
400     int32_t ret = audioManager_->GetAllAdapters(audioManager_, &descs, &size);
401     if (size > MAX_AUDIO_ADAPTER_NUM || size == 0 || descs == nullptr || ret != 0) {
402         AUDIO_ERR_LOG("Get adapters Fail");
403         return ERR_NOT_STARTED;
404     }
405 
406     // Get qualified sound card and port
407     int32_t index = SwitchAdapter(descs, adapterNameCase, port, audioPort, size);
408     if (index < 0) {
409         AUDIO_ERR_LOG("Switch Adapter Fail");
410         return ERR_NOT_STARTED;
411     }
412 
413     struct AudioAdapterDescriptor *desc = &descs[index];
414     if (audioManager_->LoadAdapter(audioManager_, desc, &audioAdapter_) != 0) {
415         AUDIO_ERR_LOG("Load Adapter Fail");
416         return ERR_NOT_STARTED;
417     }
418     CHECK_AND_RETURN_RET_LOG(audioAdapter_ != nullptr, ERR_NOT_STARTED, "Load audio device failed");
419 
420     // Initialization port information, can fill through mode and other parameters
421     ret = audioAdapter_->InitAllPorts(audioAdapter_);
422     if (ret != 0) {
423         AUDIO_ERR_LOG("InitAllPorts failed");
424         return ERR_NOT_STARTED;
425     }
426 
427     if (CreateRender(audioPort) != 0) {
428         AUDIO_ERR_LOG("Create render failed");
429         return ERR_NOT_STARTED;
430     }
431 
432     rendererInited_ = true;
433 
434 #ifdef BT_DUMPFILE
435     pfd = fopen(g_audioOutTestFilePath, "wb+");
436     if (pfd == nullptr) {
437         AUDIO_ERR_LOG("Error opening pcm test file!");
438     }
439 #endif // BT_DUMPFILE
440 
441     return SUCCESS;
442 }
443 
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)444 int32_t BluetoothRendererSinkInner::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
445 {
446     int32_t ret = SUCCESS;
447     if (audioRender_ == nullptr) {
448         AUDIO_ERR_LOG("Bluetooth Render Handle is nullptr!");
449         return ERR_INVALID_HANDLE;
450     }
451 
452     if (audioMonoState_) {
453         AdjustStereoToMono(&data, len);
454     }
455 
456     if (audioBalanceState_) {
457         AdjustAudioBalance(&data, len);
458     }
459 
460 #ifdef BT_DUMPFILE
461     if (pfd) {
462         size_t writeResult = fwrite((void*)&data, 1, len, pfd);
463         if (writeResult != len) {
464             AUDIO_ERR_LOG("Failed to write the file.");
465         }
466     }
467 #endif // BT_DUMPFILE
468 
469     Trace trace("BluetoothRendererSinkInner::RenderFrame");
470     while (true) {
471         ret = audioRender_->RenderFrame(audioRender_, (void*)&data, len, &writeLen);
472         AUDIO_DEBUG_LOG("A2dp RenderFrame returns: %{public}x", ret);
473         if (ret == RENDER_FRAME_NUM) {
474             AUDIO_ERR_LOG("retry render frame...");
475             usleep(RENDER_FRAME_INTERVAL_IN_MICROSECONDS);
476             continue;
477         }
478 
479         if (ret != 0) {
480             AUDIO_ERR_LOG("A2dp RenderFrame failed ret: %{public}x", ret);
481             ret = ERR_WRITE_FAILED;
482         }
483 
484         break;
485     }
486     if (isFirstWrite_) {
487         isFirstWrite_ = false;
488         lastCallWriteTime_ = ClockTime::GetCurNano();
489     }
490     Trace trace2("BluetoothRendererSinkInner::RenderFrame sleep");
491     int64_t writeTime = BytesToNanoTime(len);
492     int64_t timeBetweenCall = ClockTime::GetCurNano() - lastCallWriteTime_;
493     int64_t sleepTime = writeTime - timeBetweenCall;
494     if (timeBetweenCall < writeTime) {
495         ClockTime::RelativeSleep(sleepTime);
496     }
497     lastCallWriteTime_ += writeTime;
498     return ret;
499 }
500 
Start(void)501 int32_t BluetoothRendererSinkInner::Start(void)
502 {
503     Trace trace("BluetoothRendererSinkInner::Start");
504     AUDIO_INFO_LOG("Start.");
505 
506     if (keepRunningLock_ == nullptr) {
507         keepRunningLock_ = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock("AudioBluetoothBackgroundPlay",
508             PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_AUDIO);
509     }
510 
511     if (keepRunningLock_ != nullptr) {
512         AUDIO_DEBUG_LOG("AudioRendBluetoothRendererSinkererSink call KeepRunningLock lock");
513         keepRunningLock_->Lock(RUNNINGLOCK_LOCK_TIMEOUTMS_LASTING); // -1 for lasting.
514     } else {
515         AUDIO_ERR_LOG("keepRunningLock_ is null, playback can not work well!");
516     }
517 
518     int32_t ret;
519 
520     if (!started_) {
521         lastCallWriteTime_ = ClockTime::GetCurNano();
522         ret = audioRender_->control.Start(reinterpret_cast<AudioHandle>(audioRender_));
523         if (!ret) {
524             started_ = true;
525             isFirstWrite_ = true;
526             return SUCCESS;
527         } else {
528             AUDIO_ERR_LOG("Start failed!");
529             return ERR_NOT_STARTED;
530         }
531     }
532 
533     return SUCCESS;
534 }
535 
SetVolume(float left,float right)536 int32_t BluetoothRendererSinkInner::SetVolume(float left, float right)
537 {
538     int32_t ret;
539     float volume;
540 
541     if (audioRender_ == nullptr) {
542         AUDIO_ERR_LOG("SetVolume failed audioRender_ null");
543         return ERR_INVALID_HANDLE;
544     }
545 
546     leftVolume_ = left;
547     rightVolume_ = right;
548     if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
549         volume = rightVolume_;
550     } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
551         volume = leftVolume_;
552     } else {
553         volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
554     }
555 
556     ret = audioRender_->volume.SetVolume(reinterpret_cast<AudioHandle>(audioRender_), volume);
557     if (ret) {
558         AUDIO_ERR_LOG("Set volume failed!");
559     }
560 
561     return ret;
562 }
563 
GetVolume(float & left,float & right)564 int32_t BluetoothRendererSinkInner::GetVolume(float &left, float &right)
565 {
566     left = leftVolume_;
567     right = rightVolume_;
568     return SUCCESS;
569 }
570 
GetLatency(uint32_t * latency)571 int32_t BluetoothRendererSinkInner::GetLatency(uint32_t *latency)
572 {
573     if (audioRender_ == nullptr) {
574         AUDIO_ERR_LOG("GetLatency failed audio render null");
575         return ERR_INVALID_HANDLE;
576     }
577 
578     if (!latency) {
579         AUDIO_ERR_LOG("GetLatency failed latency null");
580         return ERR_INVALID_PARAM;
581     }
582 
583     uint32_t hdiLatency;
584     if (audioRender_->GetLatency(audioRender_, &hdiLatency) == 0) {
585         *latency = hdiLatency;
586         return SUCCESS;
587     } else {
588         return ERR_OPERATION_FAILED;
589     }
590 }
591 
GetTransactionId(uint64_t * transactionId)592 int32_t BluetoothRendererSinkInner::GetTransactionId(uint64_t *transactionId)
593 {
594     AUDIO_INFO_LOG("GetTransactionId in");
595 
596     if (audioRender_ == nullptr) {
597         AUDIO_ERR_LOG("GetTransactionId failed audio render null");
598         return ERR_INVALID_HANDLE;
599     }
600 
601     if (!transactionId) {
602         AUDIO_ERR_LOG("GetTransactionId failed transactionId null");
603         return ERR_INVALID_PARAM;
604     }
605 
606     *transactionId = reinterpret_cast<uint64_t>(audioRender_);
607     return SUCCESS;
608 }
609 
Stop(void)610 int32_t BluetoothRendererSinkInner::Stop(void)
611 {
612     Trace trace("BluetoothRendererSinkInner::Stop");
613     AUDIO_INFO_LOG("Stop in");
614     if (keepRunningLock_ != nullptr) {
615         AUDIO_INFO_LOG("BluetoothRendererSink call KeepRunningLock UnLock");
616         keepRunningLock_->UnLock();
617     } else {
618         AUDIO_ERR_LOG("keepRunningLock_ is null, playback can not work well!");
619     }
620     int32_t ret;
621 
622     if (audioRender_ == nullptr) {
623         AUDIO_ERR_LOG("Stop failed audioRender_ null");
624         return ERR_INVALID_HANDLE;
625     }
626 
627     if (started_) {
628         AUDIO_DEBUG_LOG("Stop control before");
629         ret = audioRender_->control.Stop(reinterpret_cast<AudioHandle>(audioRender_));
630         AUDIO_DEBUG_LOG("Stop control after");
631         if (!ret) {
632             started_ = false;
633             paused_ = false;
634             return SUCCESS;
635         } else {
636             AUDIO_ERR_LOG("Stop failed!");
637             return ERR_OPERATION_FAILED;
638         }
639     }
640 
641     return SUCCESS;
642 }
643 
Pause(void)644 int32_t BluetoothRendererSinkInner::Pause(void)
645 {
646     int32_t ret;
647 
648     if (audioRender_ == nullptr) {
649         AUDIO_ERR_LOG("Pause failed audioRender_ null");
650         return ERR_INVALID_HANDLE;
651     }
652 
653     if (!started_) {
654         AUDIO_ERR_LOG("Pause invalid state!");
655         return ERR_OPERATION_FAILED;
656     }
657 
658     if (!paused_) {
659         ret = audioRender_->control.Pause(reinterpret_cast<AudioHandle>(audioRender_));
660         if (!ret) {
661             paused_ = true;
662             return SUCCESS;
663         } else {
664             AUDIO_ERR_LOG("Pause failed!");
665             return ERR_OPERATION_FAILED;
666         }
667     }
668 
669     return SUCCESS;
670 }
671 
Resume(void)672 int32_t BluetoothRendererSinkInner::Resume(void)
673 {
674     int32_t ret;
675 
676     if (audioRender_ == nullptr) {
677         AUDIO_ERR_LOG("Resume failed audioRender_ null");
678         return ERR_INVALID_HANDLE;
679     }
680 
681     if (!started_) {
682         AUDIO_ERR_LOG("Resume invalid state!");
683         return ERR_OPERATION_FAILED;
684     }
685 
686     if (paused_) {
687         ret = audioRender_->control.Resume(reinterpret_cast<AudioHandle>(audioRender_));
688         if (!ret) {
689             lastCallWriteTime_ = ClockTime::GetCurNano();
690             paused_ = false;
691             isFirstWrite_ = true;
692             return SUCCESS;
693         } else {
694             AUDIO_ERR_LOG("Resume failed!");
695             return ERR_OPERATION_FAILED;
696         }
697     }
698 
699     return SUCCESS;
700 }
701 
Reset(void)702 int32_t BluetoothRendererSinkInner::Reset(void)
703 {
704     int32_t ret;
705 
706     if (started_ && audioRender_ != nullptr) {
707         ret = audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
708         if (!ret) {
709             return SUCCESS;
710         } else {
711             AUDIO_ERR_LOG("Reset failed!");
712             return ERR_OPERATION_FAILED;
713         }
714     }
715 
716     return ERR_OPERATION_FAILED;
717 }
718 
Flush(void)719 int32_t BluetoothRendererSinkInner::Flush(void)
720 {
721     int32_t ret;
722 
723     if (started_ && audioRender_ != nullptr) {
724         ret = audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
725         if (!ret) {
726             return SUCCESS;
727         } else {
728             AUDIO_ERR_LOG("Flush failed!");
729             return ERR_OPERATION_FAILED;
730         }
731     }
732 
733     return ERR_OPERATION_FAILED;
734 }
735 
SetAudioMonoState(bool audioMono)736 void BluetoothRendererSinkInner::SetAudioMonoState(bool audioMono)
737 {
738     audioMonoState_ = audioMono;
739 }
740 
SetAudioBalanceValue(float audioBalance)741 void BluetoothRendererSinkInner::SetAudioBalanceValue(float audioBalance)
742 {
743     // reset the balance coefficient value firstly
744     leftBalanceCoef_ = 1.0f;
745     rightBalanceCoef_ = 1.0f;
746 
747     if (std::abs(audioBalance) <= std::numeric_limits<float>::epsilon()) {
748         // audioBalance is equal to 0.0f
749         audioBalanceState_ = false;
750     } else {
751         // audioBalance is not equal to 0.0f
752         audioBalanceState_ = true;
753         // calculate the balance coefficient
754         if (audioBalance > 0.0f) {
755             leftBalanceCoef_ -= audioBalance;
756         } else if (audioBalance < 0.0f) {
757             rightBalanceCoef_ += audioBalance;
758         }
759     }
760 }
761 
AdjustStereoToMono(char * data,uint64_t len)762 void BluetoothRendererSinkInner::AdjustStereoToMono(char *data, uint64_t len)
763 {
764     if (attr_.channel != STEREO_CHANNEL_COUNT) {
765         // only stereo is surpported now (stereo channel count is 2)
766         AUDIO_ERR_LOG("AdjustStereoToMono: Unsupported channel number: %{public}d",
767             attr_.channel);
768         return;
769     }
770     switch (attr_.format) {
771         case AUDIO_FORMAT_TYPE_PCM_8_BIT: {
772             // this function needs to be further tested for usability
773             AdjustStereoToMonoForPCM8Bit(reinterpret_cast<int8_t *>(data), len);
774             break;
775         }
776         case AUDIO_FORMAT_TYPE_PCM_16_BIT: {
777             AdjustStereoToMonoForPCM16Bit(reinterpret_cast<int16_t *>(data), len);
778             break;
779         }
780         case AUDIO_FORMAT_TYPE_PCM_24_BIT: {
781             // this function needs to be further tested for usability
782             AdjustStereoToMonoForPCM24Bit(reinterpret_cast<int8_t *>(data), len);
783             break;
784         }
785         case AUDIO_FORMAT_TYPE_PCM_32_BIT: {
786             AdjustStereoToMonoForPCM32Bit(reinterpret_cast<int32_t *>(data), len);
787             break;
788         }
789         default: {
790             // if the audio format is unsupported, the audio data will not be changed
791             AUDIO_ERR_LOG("AdjustStereoToMono: Unsupported audio format: %{public}d",
792                 attr_.format);
793             break;
794         }
795     }
796 }
797 
AdjustAudioBalance(char * data,uint64_t len)798 void BluetoothRendererSinkInner::AdjustAudioBalance(char *data, uint64_t len)
799 {
800     if (attr_.channel != STEREO_CHANNEL_COUNT) {
801         // only stereo is surpported now (stereo channel count is 2)
802         AUDIO_ERR_LOG("AdjustAudioBalance: Unsupported channel number: %{public}d",
803             attr_.channel);
804         return;
805     }
806 
807     switch (attr_.format) {
808         case AUDIO_FORMAT_TYPE_PCM_8_BIT: {
809             // this function needs to be further tested for usability
810             AdjustAudioBalanceForPCM8Bit(reinterpret_cast<int8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
811             break;
812         }
813         case AUDIO_FORMAT_TYPE_PCM_16_BIT: {
814             AdjustAudioBalanceForPCM16Bit(reinterpret_cast<int16_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
815             break;
816         }
817         case AUDIO_FORMAT_TYPE_PCM_24_BIT: {
818             // this function needs to be further tested for usability
819             AdjustAudioBalanceForPCM24Bit(reinterpret_cast<int8_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
820             break;
821         }
822         case AUDIO_FORMAT_TYPE_PCM_32_BIT: {
823             AdjustAudioBalanceForPCM32Bit(reinterpret_cast<int32_t *>(data), len, leftBalanceCoef_, rightBalanceCoef_);
824             break;
825         }
826         default: {
827             // if the audio format is unsupported, the audio data will not be changed
828             AUDIO_ERR_LOG("AdjustAudioBalance: Unsupported audio format: %{public}d",
829                 attr_.format);
830             break;
831         }
832     }
833 }
HdiFormatToByte(HDI::Audio_Bluetooth::AudioFormat format)834 static uint32_t HdiFormatToByte(HDI::Audio_Bluetooth::AudioFormat format)
835 {
836     return PcmFormatToBits(format) / BIT_TO_BYTES;
837 }
838 
BytesToNanoTime(size_t lens)839 int64_t BluetoothRendererSinkInner::BytesToNanoTime(size_t lens)
840 {
841     int64_t res = AUDIO_NS_PER_SECOND * lens / (attr_.sampleRate * attr_.channel * HdiFormatToByte(attr_.format));
842     return res;
843 }
844 } // namespace AudioStandard
845 } // namespace OHOS
846