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