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