1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef LOG_TAG
16 #define LOG_TAG "FastAudioRendererSinkInner"
17 #endif
18
19 #include "fast_audio_renderer_sink.h"
20
21 #include <cinttypes>
22 #include <climits>
23 #include <cstdio>
24 #include <cstring>
25 #include <dlfcn.h>
26 #include <list>
27 #include <mutex>
28 #include <string>
29 #include <unistd.h>
30
31 #include <sys/mman.h>
32 #ifdef FEATURE_POWER_MANAGER
33 #include "power_mgr_client.h"
34 #include "running_lock.h"
35 #include "audio_running_lock_manager.h"
36 #endif
37 #include "securec.h"
38 #include "v4_0/iaudio_manager.h"
39
40 #include "audio_errors.h"
41 #include "audio_hdi_log.h"
42 #include "audio_utils.h"
43
44 using namespace std;
45
46 namespace OHOS {
47 namespace AudioStandard {
48 namespace {
49 const int32_t HALF_FACTOR = 2;
50 const uint32_t MAX_AUDIO_ADAPTER_NUM = 5;
51 const float DEFAULT_VOLUME_LEVEL = 1.0f;
52 const uint32_t AUDIO_CHANNELCOUNT = 2;
53 const uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 3840;
54 const uint32_t INT_32_MAX = 0x7fffffff;
55 const uint32_t PCM_8_BIT = 8;
56 const uint32_t PCM_16_BIT = 16;
57 const uint32_t PCM_24_BIT = 24;
58 const uint32_t PCM_32_BIT = 32;
59 const int64_t SECOND_TO_NANOSECOND = 1000000000;
60 const int INVALID_FD = -1;
61 const unsigned int XCOLLIE_TIME_OUT_SECONDS = 10;
62 }
63
64 class FastAudioRendererSinkInner : public FastAudioRendererSink {
65 public:
66 int32_t Init(const IAudioSinkAttr &attr) override;
67 bool IsInited(void) override;
68 void DeInit(void) override;
69
70 int32_t Start(void) override;
71 int32_t Stop(void) override;
72 int32_t Flush(void) override;
73 int32_t Reset(void) override;
74 int32_t Pause(void) override;
75 int32_t Resume(void) override;
76
77 int32_t SuspendRenderSink(void) override;
78 int32_t RestoreRenderSink(void) override;
79
80 int32_t RenderFrame(char &data, uint64_t len, uint64_t &writeLen) override;
81 int32_t SetVolume(float left, float right) override;
82 int32_t GetVolume(float &left, float &right) override;
83 int32_t SetVoiceVolume(float volume) override;
84 int32_t GetLatency(uint32_t *latency) override;
85 int32_t GetTransactionId(uint64_t *transactionId) override;
86 int32_t SetAudioScene(AudioScene audioScene, std::vector<DeviceType> &activeDevices) override;
87 int32_t SetOutputRoutes(std::vector<DeviceType> &outputDevices) override;
88 void ResetOutputRouteForDisconnect(DeviceType device) override;
89
90 void SetAudioParameter(const AudioParamKey key, const std::string &condition, const std::string &value) override;
91 std::string GetAudioParameter(const AudioParamKey key, const std::string &condition) override;
92 void RegisterParameterCallback(IAudioSinkCallback* callback) override;
93
94 void SetAudioMonoState(bool audioMono) override;
95 void SetAudioBalanceValue(float audioBalance) override;
96
97 int32_t GetPresentationPosition(uint64_t& frames, int64_t& timeSec, int64_t& timeNanoSec) override;
98
99 int32_t GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe,
100 uint32_t &byteSizePerFrame) override;
101 int32_t GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec) override;
102 float GetMaxAmplitude() override;
103 int32_t SetPaPower(int32_t flag) override;
104 int32_t SetPriPaPower() override;
105
106 int32_t UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size) final;
107 int32_t UpdateAppsUid(const std::vector<int32_t> &appsUid) final;
108
109 FastAudioRendererSinkInner();
110 ~FastAudioRendererSinkInner();
111
112 private:
113 #ifdef FEATURE_POWER_MANAGER
114 void KeepRunningLock();
115 void KeepRunningUnlock();
116 #endif
117 int32_t PrepareMmapBuffer();
118 void ReleaseMmapBuffer();
119
120 int32_t CheckPositionTime();
121 void PreparePosition();
122
123 void InitAttrs(struct AudioSampleAttributes &attrs);
124 AudioFormat ConvertToHdiFormat(HdiAdapterFormat format);
125 int32_t CreateRender(const struct AudioPort &renderPort);
126 int32_t InitAudioManager();
127
128 private:
129 IAudioSinkAttr attr_ = {};
130 bool rendererInited_ = false;
131 bool started_ = false;
132 bool paused_ = false;
133 float leftVolume_ = 0.0f;
134 float rightVolume_ = 0.0f;
135 int32_t routeHandle_ = -1;
136 std::string adapterNameCase_ = "";
137 struct IAudioManager *audioManager_ = nullptr;
138 struct IAudioAdapter *audioAdapter_ = nullptr;
139 struct IAudioRender *audioRender_ = nullptr;
140 struct AudioAdapterDescriptor adapterDesc_ = {};
141 struct AudioPort audioPort_ = {};
142 uint32_t renderId_ = 0;
143
144 size_t bufferSize_ = 0;
145 uint32_t bufferTotalFrameSize_ = 0;
146
147 int bufferFd_ = INVALID_FD;
148 uint32_t frameSizeInByte_ = 1;
149 uint32_t eachReadFrameSize_ = 0;
150 std::mutex mutex_;
151 #ifdef FEATURE_POWER_MANAGER
152 std::shared_ptr<AudioRunningLockManager<PowerMgr::RunningLock>> runningLockManager_;
153 #endif
154
155 #ifdef DEBUG_DIRECT_USE_HDI
156 char *bufferAddresss_ = nullptr;
157 bool isFirstWrite_ = true;
158 uint64_t alreadyReadFrames_ = 0;
159 uint32_t curReadPos_ = 0;
160 uint32_t curWritePos_ = 0;
161 uint32_t writeAheadPeriod_ = 1;
162
163 int privFd_ = INVALID_FD; // invalid fd
164 #endif
165 }; // FastAudioRendererSinkInner
166
FastAudioRendererSinkInner()167 FastAudioRendererSinkInner::FastAudioRendererSinkInner()
168 : rendererInited_(false), started_(false), paused_(false), leftVolume_(DEFAULT_VOLUME_LEVEL),
169 rightVolume_(DEFAULT_VOLUME_LEVEL), audioManager_(nullptr), audioAdapter_(nullptr),
170 audioRender_(nullptr)
171 {
172 attr_ = {};
173 }
174
~FastAudioRendererSinkInner()175 FastAudioRendererSinkInner::~FastAudioRendererSinkInner()
176 {
177 FastAudioRendererSinkInner::DeInit();
178 }
179
GetInstance()180 IMmapAudioRendererSink *FastAudioRendererSink::GetInstance()
181 {
182 static FastAudioRendererSinkInner audioRenderer;
183
184 return &audioRenderer;
185 }
186
GetVoipInstance()187 IMmapAudioRendererSink *FastAudioRendererSink::GetVoipInstance()
188 {
189 static FastAudioRendererSinkInner audioVoipRenderer;
190
191 return &audioVoipRenderer;
192 }
193
CreateFastRendererSink()194 std::shared_ptr<IMmapAudioRendererSink> FastAudioRendererSink::CreateFastRendererSink()
195 {
196 std::shared_ptr<IMmapAudioRendererSink> audioRenderer = std::make_shared<FastAudioRendererSinkInner>();
197
198 return audioRenderer;
199 }
200
IsInited()201 bool FastAudioRendererSinkInner::IsInited()
202 {
203 return rendererInited_;
204 }
205
DeInit()206 void FastAudioRendererSinkInner::DeInit()
207 {
208 #ifdef FEATURE_POWER_MANAGER
209 KeepRunningUnlock();
210
211 #endif
212
213 started_ = false;
214 rendererInited_ = false;
215 if ((audioRender_ != nullptr) && (audioAdapter_ != nullptr)) {
216 audioAdapter_->DestroyRender(audioAdapter_, renderId_);
217 }
218 audioRender_ = nullptr;
219
220 if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
221 if (routeHandle_ != -1) {
222 audioAdapter_->ReleaseAudioRoute(audioAdapter_, routeHandle_);
223 }
224 audioManager_->UnloadAdapter(audioManager_, adapterDesc_.adapterName);
225 }
226 audioAdapter_ = nullptr;
227 audioManager_ = nullptr;
228
229 ReleaseMmapBuffer();
230 }
231
InitAttrs(struct AudioSampleAttributes & attrs)232 void FastAudioRendererSinkInner::InitAttrs(struct AudioSampleAttributes &attrs)
233 {
234 /* Initialization of audio parameters for playback */
235 attrs.channelCount = AUDIO_CHANNELCOUNT;
236 attrs.interleaved = true;
237 attrs.streamId = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ?
238 static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_VOIP_FAST)) :
239 static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_FAST));
240 attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
241 attrs.isBigEndian = false;
242 attrs.isSignedData = true;
243 attrs.stopThreshold = INT_32_MAX;
244 attrs.silenceThreshold = 0;
245 }
246
SwitchAdapterRender(struct AudioAdapterDescriptor * descs,string adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort & renderPort,int32_t size)247 static int32_t SwitchAdapterRender(struct AudioAdapterDescriptor *descs, string adapterNameCase,
248 enum AudioPortDirection portFlag, struct AudioPort &renderPort, int32_t size)
249 {
250 if (descs == nullptr) {
251 return ERROR;
252 }
253 for (int32_t index = 0; index < size; index++) {
254 struct AudioAdapterDescriptor *desc = &descs[index];
255 if (desc == nullptr || desc->adapterName == nullptr) {
256 continue;
257 }
258 if (strcmp(desc->adapterName, adapterNameCase.c_str())) {
259 continue;
260 }
261 for (uint32_t port = 0; port < desc->portsLen; port++) {
262 // Only find out the port of out in the sound card
263 if (desc->ports[port].dir == portFlag) {
264 renderPort = desc->ports[port];
265 return index;
266 }
267 }
268 }
269 AUDIO_ERR_LOG("SwitchAdapterRender Fail");
270
271 return ERR_INVALID_INDEX;
272 }
273
InitAudioManager()274 int32_t FastAudioRendererSinkInner::InitAudioManager()
275 {
276 AUDIO_INFO_LOG("Initialize audio proxy manager");
277
278 audioManager_ = IAudioManagerGet(false);
279 if (audioManager_ == nullptr) {
280 return ERR_INVALID_HANDLE;
281 }
282
283 return 0;
284 }
285
PcmFormatToBits(HdiAdapterFormat format)286 uint32_t PcmFormatToBits(HdiAdapterFormat format)
287 {
288 switch (format) {
289 case SAMPLE_U8:
290 return PCM_8_BIT;
291 case SAMPLE_S16LE:
292 return PCM_16_BIT;
293 case SAMPLE_S24LE:
294 return PCM_24_BIT;
295 case SAMPLE_S32LE:
296 return PCM_32_BIT;
297 case SAMPLE_F32LE:
298 return PCM_32_BIT;
299 default:
300 return PCM_24_BIT;
301 }
302 }
303
GetMmapBufferInfo(int & fd,uint32_t & totalSizeInframe,uint32_t & spanSizeInframe,uint32_t & byteSizePerFrame)304 int32_t FastAudioRendererSinkInner::GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe,
305 uint32_t &byteSizePerFrame)
306 {
307 CHECK_AND_RETURN_RET_LOG(bufferFd_ != INVALID_FD, ERR_INVALID_HANDLE, "buffer fd has been released!");
308 fd = bufferFd_;
309 totalSizeInframe = bufferTotalFrameSize_;
310 spanSizeInframe = eachReadFrameSize_;
311 byteSizePerFrame = PcmFormatToBits(attr_.format) * attr_.channel / PCM_8_BIT;
312 return SUCCESS;
313 }
314
GetMmapHandlePosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)315 int32_t FastAudioRendererSinkInner::GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
316 {
317 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "Audio render is null!");
318
319 struct AudioTimeStamp timestamp = {};
320 int32_t ret = audioRender_->GetMmapPosition(audioRender_, &frames, ×tamp);
321 CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "Hdi GetMmapPosition filed, ret:%{public}d!", ret);
322 #ifdef DEBUG_DIRECT_USE_HDI
323 alreadyReadFrames_ = frames; // frames already read.
324 curReadPos_ = frameSizeInByte_ * (frames - bufferTotalFrameSize_ * (frames / bufferTotalFrameSize_));
325 CHECK_AND_RETURN_RET_LOG((curReadPos_ >= 0 && curReadPos_ < bufferSize_), ERR_INVALID_PARAM, "curReadPos invalid");
326 AUDIO_DEBUG_LOG("GetMmapHandlePosition frames[:%{public}" PRIu64 "] tvsec:%{public}" PRId64 " tvNSec:"
327 "%{public}" PRId64 " alreadyReadFrames:%{public}" PRId64 " curReadPos[%{public}d]",
328 frames, timestamp.tvSec, timestamp.tvNSec, alreadyReadFrames_, curReadPos_);
329 #endif
330
331 int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it.
332 CHECK_AND_RETURN_RET_LOG(timestamp.tvSec >= 0 && timestamp.tvSec <= maxSec && timestamp.tvNSec >= 0 &&
333 timestamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED,
334 "Hdi GetMmapPosition get invaild second:%{public}" PRId64 " or nanosecond:%{public}" PRId64 " !",
335 timestamp.tvSec, timestamp.tvNSec);
336 timeSec = timestamp.tvSec;
337 timeNanoSec = timestamp.tvNSec;
338
339 return SUCCESS;
340 }
341
ReleaseMmapBuffer()342 void FastAudioRendererSinkInner::ReleaseMmapBuffer()
343 {
344 #ifdef DEBUG_DIRECT_USE_HDI
345 if (bufferAddresss_ != nullptr) {
346 munmap(bufferAddresss_, bufferSize_);
347 bufferAddresss_ = nullptr;
348 bufferSize_ = 0;
349 AUDIO_INFO_LOG("ReleaseMmapBuffer end.");
350 } else {
351 AUDIO_WARNING_LOG("ReleaseMmapBuffer buffer already null.");
352 }
353 if (privFd_ != INVALID_FD) {
354 CloseFd(privFd_);
355 privFd_ = INVALID_FD;
356 }
357 #endif
358 if (bufferFd_ != INVALID_FD) {
359 CloseFd(bufferFd_);
360 bufferFd_ = INVALID_FD;
361 }
362 }
363
PrepareMmapBuffer()364 int32_t FastAudioRendererSinkInner::PrepareMmapBuffer()
365 {
366 uint32_t totalBufferInMs = 40; // 5 * (6 + 2 * (1)) = 40ms, the buffer size, not latency.
367 frameSizeInByte_ = PcmFormatToBits(attr_.format) * attr_.channel / PCM_8_BIT;
368 uint32_t reqBufferFrameSize = totalBufferInMs * (attr_.sampleRate / 1000);
369
370 struct AudioMmapBufferDescriptor desc = {0};
371 int32_t ret = audioRender_->ReqMmapBuffer(audioRender_, reqBufferFrameSize, &desc);
372 CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED, "ReqMmapBuffer failed, ret:%{public}d", ret);
373 AUDIO_INFO_LOG("AudioMmapBufferDescriptor memoryAddress[%{private}p] memoryFd[%{public}d] totalBufferFrames"
374 "[%{public}d] transferFrameSize[%{public}d] isShareable[%{public}d] offset[%{public}d]", desc.memoryAddress,
375 desc.memoryFd, desc.totalBufferFrames, desc.transferFrameSize, desc.isShareable, desc.offset);
376
377 bufferFd_ = desc.memoryFd; // fcntl(fd, 1030,3) after dup?
378 int32_t periodFrameMaxSize = 1920000; // 192khz * 10s
379 CHECK_AND_RETURN_RET_LOG(desc.totalBufferFrames >= 0 && desc.transferFrameSize >= 0 &&
380 desc.transferFrameSize <= periodFrameMaxSize, ERR_OPERATION_FAILED,
381 "ReqMmapBuffer invalid values: totalBufferFrames[%{public}d] transferFrameSize[%{public}d]",
382 desc.totalBufferFrames, desc.transferFrameSize);
383 bufferTotalFrameSize_ = static_cast<uint32_t>(desc.totalBufferFrames); // 1440 ~ 3840
384 eachReadFrameSize_ = static_cast<uint32_t>(desc.transferFrameSize); // 240
385
386 CHECK_AND_RETURN_RET_LOG(frameSizeInByte_ <= ULLONG_MAX / bufferTotalFrameSize_, ERR_OPERATION_FAILED,
387 "BufferSize will overflow!");
388 bufferSize_ = bufferTotalFrameSize_ * frameSizeInByte_;
389 #ifdef DEBUG_DIRECT_USE_HDI
390 privFd_ = dup(bufferFd_);
391 bufferAddresss_ = (char *)mmap(nullptr, bufferSize_, PROT_READ | PROT_WRITE, MAP_SHARED, privFd_, 0);
392 CHECK_AND_RETURN_RET_LOG(bufferAddresss_ != nullptr && bufferAddresss_ != MAP_FAILED, ERR_OPERATION_FAILED,
393 "mmap buffer failed!");
394 #endif
395 return SUCCESS;
396 }
397
ConvertToHdiFormat(HdiAdapterFormat format)398 AudioFormat FastAudioRendererSinkInner::ConvertToHdiFormat(HdiAdapterFormat format)
399 {
400 AudioFormat hdiFormat;
401 switch (format) {
402 case SAMPLE_U8:
403 hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
404 break;
405 case SAMPLE_S16:
406 hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
407 break;
408 case SAMPLE_S24:
409 hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
410 break;
411 case SAMPLE_S32:
412 hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
413 break;
414 default:
415 hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
416 break;
417 }
418
419 return hdiFormat;
420 }
421
CreateRender(const struct AudioPort & renderPort)422 int32_t FastAudioRendererSinkInner::CreateRender(const struct AudioPort &renderPort)
423 {
424 int32_t ret;
425 struct AudioSampleAttributes param;
426 InitAttrs(param);
427 param.type = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ? AUDIO_MMAP_VOIP : AUDIO_MMAP_NOIRQ;
428 param.sampleRate = attr_.sampleRate;
429 param.channelCount = attr_.channel;
430 if (param.channelCount == MONO) {
431 param.channelLayout = CH_LAYOUT_MONO;
432 } else if (param.channelCount == STEREO) {
433 param.channelLayout = CH_LAYOUT_STEREO;
434 }
435 param.format = ConvertToHdiFormat(attr_.format);
436 param.frameSize = PcmFormatToBits(attr_.format) * param.channelCount / PCM_8_BIT;
437 param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize); // not passed in hdi
438 AUDIO_INFO_LOG("Type: %{public}d, sampleRate: %{public}u, channel: %{public}d, format: %{public}d, "
439 "device:%{public}d", param.type, param.sampleRate, param.channelCount, param.format, attr_.deviceType);
440 struct AudioDeviceDescriptor deviceDesc;
441 deviceDesc.portId = renderPort.portId;
442 switch (static_cast<DeviceType>(attr_.deviceType)) {
443 case DEVICE_TYPE_EARPIECE:
444 deviceDesc.pins = PIN_OUT_EARPIECE;
445 break;
446 case DEVICE_TYPE_SPEAKER:
447 deviceDesc.pins = PIN_OUT_SPEAKER;
448 break;
449 case DEVICE_TYPE_WIRED_HEADSET:
450 deviceDesc.pins = PIN_OUT_HEADSET;
451 break;
452 case DEVICE_TYPE_USB_HEADSET:
453 deviceDesc.pins = PIN_OUT_USB_EXT;
454 break;
455 case DEVICE_TYPE_BLUETOOTH_SCO:
456 deviceDesc.pins = PIN_OUT_BLUETOOTH_SCO;
457 break;
458 default:
459 deviceDesc.pins = PIN_OUT_SPEAKER;
460 break;
461 }
462 char desc[] = "";
463 deviceDesc.desc = desc;
464 ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, ¶m, &audioRender_, &renderId_);
465 if (ret != 0 || audioRender_ == nullptr) {
466 AUDIO_ERR_LOG("AudioDeviceCreateRender failed, ret is :%{public}d", ret);
467 audioManager_->UnloadAdapter(audioManager_, adapterDesc_.adapterName);
468 return ERR_NOT_STARTED;
469 }
470
471 return SUCCESS;
472 }
473
Init(const IAudioSinkAttr & attr)474 int32_t FastAudioRendererSinkInner::Init(const IAudioSinkAttr &attr)
475 {
476 AUDIO_INFO_LOG("FastAudioRendererSinkInner::Init");
477 attr_ = attr;
478 adapterNameCase_ = attr_.adapterName; // Set sound card information
479 enum AudioPortDirection port = PORT_OUT; // Set port information
480
481 CHECK_AND_RETURN_RET_LOG(InitAudioManager() == 0, ERR_NOT_STARTED, "Init audio manager Fail");
482
483 uint32_t size = MAX_AUDIO_ADAPTER_NUM;
484 AudioAdapterDescriptor descs[MAX_AUDIO_ADAPTER_NUM];
485 if (audioManager_ == nullptr) {
486 AUDIO_ERR_LOG("The audioManager is nullptr!");
487 return ERROR;
488 }
489 int32_t ret = audioManager_->GetAllAdapters(audioManager_,
490 (struct AudioAdapterDescriptor *)&descs, &size);
491 CHECK_AND_RETURN_RET_LOG(size <= MAX_AUDIO_ADAPTER_NUM && size != 0 && ret == 0, ERR_NOT_STARTED,
492 "Get adapters Fail");
493
494 int32_t index = SwitchAdapterRender((struct AudioAdapterDescriptor *)&descs, adapterNameCase_, port, audioPort_,
495 size);
496 CHECK_AND_RETURN_RET_LOG(index >= 0, ERR_NOT_STARTED, "Switch Adapter Fail");
497
498 adapterDesc_ = descs[index];
499 int32_t result = audioManager_->LoadAdapter(audioManager_, &adapterDesc_, &audioAdapter_);
500 CHECK_AND_RETURN_RET_LOG(result == 0, ERR_NOT_STARTED, "Load Adapter Fail");
501 CHECK_AND_RETURN_RET_LOG(audioAdapter_ != nullptr, ERR_NOT_STARTED, "Load audio device failed");
502
503 // Initialization port information, can fill through mode and other parameters
504 ret = audioAdapter_->InitAllPorts(audioAdapter_);
505 CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_NOT_STARTED, "InitAllPorts failed");
506
507 CHECK_AND_RETURN_RET_LOG(CreateRender(audioPort_) == SUCCESS && PrepareMmapBuffer() == SUCCESS,
508 ERR_NOT_STARTED, "Create render failed, Audio Port: %{public}d", audioPort_.portId);
509
510 rendererInited_ = true;
511
512 return SUCCESS;
513 }
514
PreparePosition()515 void FastAudioRendererSinkInner::PreparePosition()
516 {
517 #ifdef DEBUG_DIRECT_USE_HDI
518 isFirstWrite_ = false;
519 uint64_t frames = 0;
520 int64_t timeSec = 0;
521 int64_t timeNanoSec = 0;
522 GetMmapHandlePosition(frames, timeSec, timeNanoSec); // get first start position
523 int32_t periodByteSize = eachReadFrameSize_ * frameSizeInByte_;
524 CHECK_AND_RETURN_LOG(periodByteSize * writeAheadPeriod_ <= ULLONG_MAX - curReadPos_, "TempPos will overflow!");
525 size_t tempPos = curReadPos_ + periodByteSize * writeAheadPeriod_; // 1 period ahead
526 curWritePos_ = (tempPos < bufferSize_ ? tempPos : tempPos - bufferSize_);
527 AUDIO_INFO_LOG("First render frame start with curReadPos_[%{public}d] curWritePos_[%{public}d]", curReadPos_,
528 curWritePos_);
529 #endif
530 }
531
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)532 int32_t FastAudioRendererSinkInner::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
533 {
534 #ifdef DEBUG_DIRECT_USE_HDI
535 int64_t stamp = ClockTime::GetCurNano();
536 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "Audio Render Handle is nullptr!");
537
538 if (len > (bufferSize_ - eachReadFrameSize_ * frameSizeInByte_ * writeAheadPeriod_)) {
539 writeLen = 0;
540 AUDIO_ERR_LOG("RenderFrame failed,too large len[%{public}" PRIu64 "]!", len);
541 return ERR_WRITE_FAILED;
542 }
543
544 if (isFirstWrite_) {
545 PreparePosition();
546 }
547
548 CHECK_AND_RETURN_RET_LOG((curWritePos_ >= 0 && curWritePos_ < bufferSize_), ERR_INVALID_PARAM,
549 "curWritePos_ invalid");
550 char *writePtr = bufferAddresss_ + curWritePos_;
551 uint64_t dataBefore = *(uint64_t *)writePtr;
552 uint64_t dataAfter = 0;
553 uint64_t tempPos = curWritePos_ + len;
554 if (tempPos <= bufferSize_) {
555 if (memcpy_s(writePtr, (bufferSize_ - curWritePos_), static_cast<void *>(&data), len)) {
556 AUDIO_ERR_LOG("copy failed");
557 return ERR_WRITE_FAILED;
558 }
559 dataAfter = *(uint64_t *)writePtr;
560 curWritePos_ = (tempPos == bufferSize_ ? 0 : tempPos);
561 } else {
562 AUDIO_DEBUG_LOG("(tempPos%{public}" PRIu64 ")curWritePos_ + len > bufferSize_", tempPos);
563 size_t writeableSize = bufferSize_ - curWritePos_;
564 if (memcpy_s(writePtr, writeableSize, static_cast<void *>(&data), writeableSize) ||
565 memcpy_s(bufferAddresss_, bufferSize_, static_cast<void *>((char *)&data + writeableSize),
566 (len - writeableSize))) {
567 AUDIO_ERR_LOG("copy failed");
568 return ERR_WRITE_FAILED;
569 }
570 curWritePos_ = len - writeableSize;
571 }
572 writeLen = len;
573
574 stamp = (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND;
575 AUDIO_DEBUG_LOG("Render len[%{public}" PRIu64 "] cost[%{public}" PRId64 "]ms curWritePos[%{public}d] dataBefore"
576 "<%{public}" PRIu64 "> dataAfter<%{public}" PRIu64 ">", len, stamp, curWritePos_, dataBefore, dataAfter);
577 return SUCCESS;
578 #else
579 AUDIO_WARNING_LOG("RenderFrame is not supported.");
580 return ERR_NOT_SUPPORTED;
581 #endif
582 }
583
GetMaxAmplitude()584 float FastAudioRendererSinkInner::GetMaxAmplitude()
585 {
586 AUDIO_WARNING_LOG("getMaxAmplitude in fast_audio_renderder_sink not support");
587 return 0;
588 }
589
SetPaPower(int32_t flag)590 int32_t FastAudioRendererSinkInner::SetPaPower(int32_t flag)
591 {
592 (void)flag;
593 return ERR_NOT_SUPPORTED;
594 }
595
SetPriPaPower()596 int32_t FastAudioRendererSinkInner::SetPriPaPower()
597 {
598 return ERR_NOT_SUPPORTED;
599 }
600
CheckPositionTime()601 int32_t FastAudioRendererSinkInner::CheckPositionTime()
602 {
603 int32_t tryCount = 50;
604 uint64_t frames = 0;
605 int64_t timeSec = 0;
606 int64_t timeNanoSec = 0;
607 int64_t maxHandleCost = 10000000; // ns
608 int64_t waitTime = 2000000; // 2ms
609 while (tryCount-- > 0) {
610 ClockTime::RelativeSleep(waitTime); // us
611 int32_t ret = GetMmapHandlePosition(frames, timeSec, timeNanoSec);
612 int64_t curTime = ClockTime::GetCurNano();
613 int64_t curSec = curTime / AUDIO_NS_PER_SECOND;
614 int64_t curNanoSec = curTime - curSec * AUDIO_NS_PER_SECOND;
615 if (ret != SUCCESS || curSec != timeSec || curNanoSec - timeNanoSec > maxHandleCost) {
616 AUDIO_WARNING_LOG("CheckPositionTime[%{public}d]:ret %{public}d", tryCount, ret);
617 continue;
618 } else {
619 AUDIO_INFO_LOG("CheckPositionTime end, position and time is ok.");
620 return SUCCESS;
621 }
622 }
623 return ERROR;
624 }
625
Start(void)626 int32_t FastAudioRendererSinkInner::Start(void)
627 {
628 std::lock_guard<std::mutex> lock(mutex_);
629 Trace trace("FastAudioRendererSinkInner::Start");
630 AudioXCollie sourceXCollie("FastAudioRendererSinkInner::Start", XCOLLIE_TIME_OUT_SECONDS);
631 AUDIO_INFO_LOG("FastAudioRendererSinkInner::Start");
632 int64_t stamp = ClockTime::GetCurNano();
633 int32_t ret;
634
635 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
636 "FastAudioRendererSink::Start audioRender_ null!");
637
638 if (!started_) {
639 ret = audioRender_->Start(audioRender_);
640 CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_NOT_STARTED,
641 "FastAudioRendererSink::Start failed!");
642 int32_t err = CheckPositionTime();
643 CHECK_AND_RETURN_RET_LOG(err == SUCCESS, ERR_NOT_STARTED,
644 "FastAudioRendererSink::CheckPositionTime failed!");
645 }
646 #ifdef FEATURE_POWER_MANAGER
647 KeepRunningLock();
648 #endif
649 started_ = true;
650 AUDIO_DEBUG_LOG("Start cost[%{public}" PRId64 "]ms", (ClockTime::GetCurNano() - stamp) / AUDIO_US_PER_SECOND);
651 return SUCCESS;
652 }
653 #ifdef FEATURE_POWER_MANAGER
KeepRunningLock()654 void FastAudioRendererSinkInner::KeepRunningLock()
655 {
656 std::shared_ptr<PowerMgr::RunningLock> keepRunningLock;
657 if (runningLockManager_ == nullptr) {
658 WatchTimeout guard("PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock:KeepRunningLock");
659 keepRunningLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock("AudioFastBackgroundPlay",
660 PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_AUDIO);
661 guard.CheckCurrTimeout();
662 if (keepRunningLock) {
663 runningLockManager_ = std::make_shared<AudioRunningLockManager<PowerMgr::RunningLock>> (keepRunningLock);
664 }
665 }
666
667 if (runningLockManager_ != nullptr) {
668 int32_t timeOut = -1; // -1 for lasting.
669 AUDIO_INFO_LOG("keepRunningLock lock result: %{public}d",
670 runningLockManager_->Lock(timeOut)); // -1 for lasting.
671 } else {
672 AUDIO_ERR_LOG("keepRunningLock is null, playback can not work well!");
673 }
674 }
675 #endif
676
677 #ifdef FEATURE_POWER_MANAGER
KeepRunningUnlock()678 void FastAudioRendererSinkInner::KeepRunningUnlock()
679 {
680 if (runningLockManager_ != nullptr) {
681 AUDIO_INFO_LOG("keepRunningLock unLock");
682 runningLockManager_->UnLock();
683 } else {
684 AUDIO_WARNING_LOG("keepRunningLock is null, playback can not work well!");
685 }
686 }
687 #endif
688
689
SetVolume(float left,float right)690 int32_t FastAudioRendererSinkInner::SetVolume(float left, float right)
691 {
692 int32_t ret;
693 float volume;
694
695 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
696 "FastAudioRendererSink::SetVolume failed audioRender_ null");
697
698 leftVolume_ = left;
699 rightVolume_ = right;
700 if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
701 volume = rightVolume_;
702 } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
703 volume = leftVolume_;
704 } else {
705 volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
706 }
707
708 AUDIO_INFO_LOG("Set hdi volume to %{public}f", volume);
709 ret = audioRender_->SetVolume(audioRender_, volume);
710 if (ret) {
711 AUDIO_ERR_LOG("FastAudioRendererSink::Set volume failed!");
712 }
713
714 return ret;
715 }
716
GetVolume(float & left,float & right)717 int32_t FastAudioRendererSinkInner::GetVolume(float &left, float &right)
718 {
719 left = leftVolume_;
720 right = rightVolume_;
721 return SUCCESS;
722 }
723
SetVoiceVolume(float volume)724 int32_t FastAudioRendererSinkInner::SetVoiceVolume(float volume)
725 {
726 AUDIO_ERR_LOG("FastAudioRendererSink SetVoiceVolume not supported.");
727 return ERR_NOT_SUPPORTED;
728 }
729
SetAudioScene(AudioScene audioScene,std::vector<DeviceType> & activeDevices)730 int32_t FastAudioRendererSinkInner::SetAudioScene(AudioScene audioScene, std::vector<DeviceType> &activeDevices)
731 {
732 AUDIO_ERR_LOG("FastAudioRendererSink SetAudioScene not supported.");
733 return ERR_NOT_SUPPORTED;
734 }
735
SetOutputRoutes(std::vector<DeviceType> & outputDevices)736 int32_t FastAudioRendererSinkInner::SetOutputRoutes(std::vector<DeviceType> &outputDevices)
737 {
738 AUDIO_ERR_LOG("SetOutputRoutes not supported.");
739 return ERR_NOT_SUPPORTED;
740 }
741
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)742 void FastAudioRendererSinkInner::SetAudioParameter(const AudioParamKey key, const std::string &condition,
743 const std::string &value)
744 {
745 AUDIO_ERR_LOG("FastAudioRendererSink SetAudioParameter not supported.");
746 return;
747 }
748
GetAudioParameter(const AudioParamKey key,const std::string & condition)749 std::string FastAudioRendererSinkInner::GetAudioParameter(const AudioParamKey key, const std::string &condition)
750 {
751 AUDIO_INFO_LOG("GetAudioParameter, key: %{public}d, condition: %{public}s",
752 key, condition.c_str());
753 AudioExtParamKey hdiKey = AudioExtParamKey(key);
754 char value[PARAM_VALUE_LENTH];
755 CHECK_AND_RETURN_RET_LOG(audioAdapter_ != nullptr, "",
756 "GetAudioParameter failed, audioAdapter_ is null");
757 int32_t ret = audioAdapter_->GetExtraParams(audioAdapter_, hdiKey, condition.c_str(),
758 value, PARAM_VALUE_LENTH);
759 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, "",
760 "FRSink GetAudioParameter failed, error code:%{public}d", ret);
761 return value;
762 }
763
RegisterParameterCallback(IAudioSinkCallback * callback)764 void FastAudioRendererSinkInner::RegisterParameterCallback(IAudioSinkCallback* callback)
765 {
766 AUDIO_ERR_LOG("FastAudioRendererSink RegisterParameterCallback not supported.");
767 }
768
SetAudioMonoState(bool audioMono)769 void FastAudioRendererSinkInner::SetAudioMonoState(bool audioMono)
770 {
771 AUDIO_ERR_LOG("FastAudioRendererSink SetAudioMonoState not supported.");
772 return;
773 }
774
SetAudioBalanceValue(float audioBalance)775 void FastAudioRendererSinkInner::SetAudioBalanceValue(float audioBalance)
776 {
777 AUDIO_ERR_LOG("FastAudioRendererSink SetAudioBalanceValue not supported.");
778 return;
779 }
780
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)781 int32_t FastAudioRendererSinkInner::GetPresentationPosition(uint64_t& frames, int64_t& timeSec, int64_t& timeNanoSec)
782 {
783 AUDIO_ERR_LOG("FastAudioRendererSink GetPresentationPosition not supported.");
784 return ERR_NOT_SUPPORTED;
785 }
786
GetTransactionId(uint64_t * transactionId)787 int32_t FastAudioRendererSinkInner::GetTransactionId(uint64_t *transactionId)
788 {
789 AUDIO_ERR_LOG("FastAudioRendererSink %{public}s", __func__);
790 *transactionId = 6; // 6 is the mmap device.
791 return ERR_NOT_SUPPORTED;
792 }
793
GetLatency(uint32_t * latency)794 int32_t FastAudioRendererSinkInner::GetLatency(uint32_t *latency)
795 {
796 Trace trace("FastAudioRendererSinkInner::GetLatency");
797 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
798 "GetLatency failed audio render null");
799
800 CHECK_AND_RETURN_RET_LOG(latency, ERR_INVALID_PARAM,
801 "GetLatency failed latency null");
802
803 uint32_t hdiLatency;
804 if (audioRender_->GetLatency(audioRender_, &hdiLatency) == 0) {
805 *latency = hdiLatency;
806 return SUCCESS;
807 } else {
808 return ERR_OPERATION_FAILED;
809 }
810 }
811
Stop(void)812 int32_t FastAudioRendererSinkInner::Stop(void)
813 {
814 std::lock_guard<std::mutex> lock(mutex_);
815 Trace trace("FastAudioRendererSinkInner::Stop");
816 AudioXCollie sourceXCollie("FastAudioRendererSinkInner::Stop", XCOLLIE_TIME_OUT_SECONDS);
817 AUDIO_INFO_LOG("Stop.");
818
819 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
820 "Stop failed audioRender_ null");
821 #ifdef FEATURE_POWER_MANAGER
822 KeepRunningUnlock();
823 #endif
824
825 if (started_) {
826 int32_t ret = audioRender_->Stop(audioRender_);
827 CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
828 "Stop failed! ret: %{public}d.", ret);
829 }
830 started_ = false;
831
832 return SUCCESS;
833 }
834
Pause(void)835 int32_t FastAudioRendererSinkInner::Pause(void)
836 {
837 int32_t ret;
838
839 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
840 "Pause failed audioRender_ null");
841
842 CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED,
843 "Pause invalid state!");
844
845 if (!paused_) {
846 ret = audioRender_->Pause(audioRender_);
847 CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
848 "Pause failed!");
849 }
850 paused_ = true;
851
852 return SUCCESS;
853 }
854
Resume(void)855 int32_t FastAudioRendererSinkInner::Resume(void)
856 {
857 Trace trace("FastAudioRendererSinkInner::Resume");
858 int32_t ret;
859
860 CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE,
861 "Resume failed audioRender_ null");
862
863 CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED,
864 "Resume invalid state!");
865
866 if (paused_) {
867 ret = audioRender_->Resume(audioRender_);
868 CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
869 "Resume failed!");
870 }
871 paused_ = false;
872
873 return SUCCESS;
874 }
875
SuspendRenderSink(void)876 int32_t FastAudioRendererSinkInner::SuspendRenderSink(void)
877 {
878 return SUCCESS;
879 }
880
RestoreRenderSink(void)881 int32_t FastAudioRendererSinkInner::RestoreRenderSink(void)
882 {
883 return SUCCESS;
884 }
885
Reset(void)886 int32_t FastAudioRendererSinkInner::Reset(void)
887 {
888 Trace trace("FastAudioRendererSinkInner::Reset");
889 int32_t ret;
890
891 if (started_ && audioRender_ != nullptr) {
892 ret = audioRender_->Flush(audioRender_);
893
894 CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
895 "Reset failed!");
896 }
897
898 return SUCCESS;
899 }
900
Flush(void)901 int32_t FastAudioRendererSinkInner::Flush(void)
902 {
903 Trace trace("FastAudioRendererSinkInner::Flush");
904 int32_t ret;
905
906 if (started_ && audioRender_ != nullptr) {
907 ret = audioRender_->Flush(audioRender_);
908 CHECK_AND_RETURN_RET_LOG(ret == 0, ERR_OPERATION_FAILED,
909 "Flush failed!");
910 }
911
912 return SUCCESS;
913 }
914
ResetOutputRouteForDisconnect(DeviceType device)915 void FastAudioRendererSinkInner::ResetOutputRouteForDisconnect(DeviceType device)
916 {
917 }
918
UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],const size_t size)919 int32_t FastAudioRendererSinkInner::UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS],
920 const size_t size)
921 {
922 return SUCCESS;
923 }
924
UpdateAppsUid(const std::vector<int32_t> & appsUid)925 int32_t FastAudioRendererSinkInner::UpdateAppsUid(const std::vector<int32_t> &appsUid)
926 {
927 #ifdef FEATURE_POWER_MANAGER
928 if (!runningLockManager_) {
929 return ERROR;
930 }
931
932 runningLockManager_->UpdateAppsUid(appsUid.cbegin(), appsUid.cend());
933 runningLockManager_->UpdateAppsUidToPowerMgr();
934 #endif
935
936 return SUCCESS;
937 }
938
939 } // namespace AudioStandard
940 } // namespace OHOS
941