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