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