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