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, ¶m, &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