• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 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 "ProRendererStream"
17 #endif
18 
19 #include "pro_renderer_stream_impl.h"
20 #include "audio_errors.h"
21 #include "audio_renderer_log.h"
22 #include "audio_utils.h"
23 #include "securec.h"
24 #include "policy_handler.h"
25 #include "audio_volume.h"
26 
27 namespace OHOS {
28 namespace AudioStandard {
29 constexpr uint64_t AUDIO_US_PER_S = 1000000;
30 constexpr uint64_t AUDIO_NS_PER_S = 1000000000;
31 constexpr int32_t SECOND_TO_MILLISECOND = 1000;
32 constexpr int32_t DEFAULT_BUFFER_MILLISECOND = 20;
33 constexpr int32_t DEFAULT_BUFFER_MICROSECOND = 20000000;
34 constexpr uint32_t DOUBLE_VALUE = 2;
35 constexpr int32_t DEFAULT_RESAMPLE_QUANTITY = 2;
36 constexpr int32_t STEREO_CHANNEL_COUNT = 2;
37 constexpr int32_t DEFAULT_TOTAL_SPAN_COUNT = 2;
38 constexpr int32_t DRAIN_WAIT_TIMEOUT_TIME = 100;
39 constexpr int32_t FIRST_FRAME_TIMEOUT_TIME = 500;
40 const std::string DUMP_DIRECT_STREAM_FILE = "dump_direct_audio_stream.pcm";
41 const std::string DEVICE_NAME = "primary";
42 
ProRendererStreamImpl(AudioProcessConfig processConfig,bool isDirect)43 ProRendererStreamImpl::ProRendererStreamImpl(AudioProcessConfig processConfig, bool isDirect)
44     : isDirect_(isDirect),
45       isNeedResample_(false),
46       isNeedMcr_(false),
47       isBlock_(true),
48       isDrain_(false),
49       isFirstFrame_(true),
50       privacyType_(0),
51       renderRate_(0),
52       streamIndex_(static_cast<uint32_t>(-1)),
53       currentRate_(1),
54       desSamplingRate_(0),
55       desFormat_(AudioSampleFormat::SAMPLE_S32LE),
56       byteSizePerFrame_(0),
57       spanSizeInFrame_(0),
58       totalBytesWritten_(0),
59       sinkBytesWritten_(0),
60       minBufferSize_(0),
61       status_(I_STATUS_INVALID),
62       resample_(nullptr),
63       processConfig_(processConfig),
64       downMixer_(nullptr),
65       dumpFile_(nullptr)
66 {
67     AUDIO_DEBUG_LOG("constructor");
68 }
69 
~ProRendererStreamImpl()70 ProRendererStreamImpl::~ProRendererStreamImpl()
71 {
72     AUDIO_DEBUG_LOG("deconstructor");
73     status_ = I_STATUS_INVALID;
74     DumpFileUtil::CloseDumpFile(&dumpFile_);
75 }
76 
GetDirectSampleRate(AudioSamplingRate sampleRate) const77 AudioSamplingRate ProRendererStreamImpl::GetDirectSampleRate(AudioSamplingRate sampleRate) const noexcept
78 {
79     if (processConfig_.streamType == STREAM_VOICE_CALL || processConfig_.streamType == STREAM_VOICE_COMMUNICATION) {
80         // VoIP stream type. Return the special sample rate of direct VoIP mode.
81         if (sampleRate <= AudioSamplingRate::SAMPLE_RATE_16000) {
82             return AudioSamplingRate::SAMPLE_RATE_16000;
83         } else {
84             return AudioSamplingRate::SAMPLE_RATE_48000;
85         }
86     }
87     // High resolution for music
88     AudioSamplingRate result = sampleRate;
89     switch (sampleRate) {
90         case AudioSamplingRate::SAMPLE_RATE_44100:
91             result = AudioSamplingRate::SAMPLE_RATE_48000;
92             break;
93         case AudioSamplingRate::SAMPLE_RATE_88200:
94             result = AudioSamplingRate::SAMPLE_RATE_96000;
95             break;
96         case AudioSamplingRate::SAMPLE_RATE_176400:
97             result = AudioSamplingRate::SAMPLE_RATE_192000;
98             break;
99         default:
100             break;
101     }
102     return result;
103 }
104 
GetDirectFormat(AudioSampleFormat format) const105 AudioSampleFormat ProRendererStreamImpl::GetDirectFormat(AudioSampleFormat format) const noexcept
106 {
107     if (isDirect_) {
108         // Only SAMPLE_S32LE is supported for high resolution stream.
109         return AudioSampleFormat::SAMPLE_S32LE;
110     }
111 
112     // Both SAMPLE_S16LE and SAMPLE_S32LE are supported for direct VoIP stream.
113     if (format == SAMPLE_S16LE || format == SAMPLE_S32LE) {
114         return format;
115     } else if (format == SAMPLE_F32LE) {
116         // Direct VoIP not support SAMPLE_F32LE format.It needs to be converted to S16.
117         return AudioSampleFormat::SAMPLE_S16LE;
118     } else {
119         AUDIO_WARNING_LOG("The format %{public}u is unsupported for direct VoIP. Use 32Bit.", format);
120         return AudioSampleFormat::SAMPLE_S32LE;
121     }
122 }
123 
InitParams()124 int32_t ProRendererStreamImpl::InitParams()
125 {
126     Trace trace("ProRendererStreamImpl::InitParams");
127     if (status_ != I_STATUS_INVALID) {
128         return ERR_ILLEGAL_STATE;
129     }
130     AudioStreamInfo streamInfo = processConfig_.streamInfo;
131     AUDIO_INFO_LOG("sampleSpec: channels: %{public}u, formats: %{public}d, rate: %{public}d", streamInfo.channels,
132         streamInfo.format, streamInfo.samplingRate);
133     InitBasicInfo(streamInfo);
134     size_t frameSize = spanSizeInFrame_ * streamInfo.channels;
135     uint32_t desChannels = streamInfo.channels >= STEREO_CHANNEL_COUNT ? STEREO_CHANNEL_COUNT : 1;
136     uint32_t desSpanSize = (desSamplingRate_ * DEFAULT_BUFFER_MILLISECOND) / SECOND_TO_MILLISECOND;
137     if (streamInfo.samplingRate != desSamplingRate_) {
138         Trace::Count("ProRendererStreamImpl::InitParams", streamInfo.samplingRate);
139         AUDIO_INFO_LOG("stream need resample, dest:%{public}d", desSamplingRate_);
140         isNeedResample_ = true;
141         resample_ = std::make_shared<AudioResample>(desChannels, streamInfo.samplingRate, desSamplingRate_,
142             DEFAULT_RESAMPLE_QUANTITY);
143         if (!resample_->IsResampleInit()) {
144             AUDIO_ERR_LOG("resample not supported.");
145             return ERR_INVALID_PARAM;
146         }
147         resampleSrcBuffer.resize(frameSize, 0.f);
148         resampleDesBuffer.resize(desSpanSize * desChannels, 0.f);
149         resample_->ProcessFloatResample(resampleSrcBuffer, resampleDesBuffer);
150     }
151     if (streamInfo.channels > STEREO_CHANNEL_COUNT) {
152         Trace::Count("ProRendererStreamImpl::InitParams", streamInfo.channels);
153         isNeedMcr_ = true;
154         if (!isNeedResample_) {
155             resampleSrcBuffer.resize(frameSize, 0.f);
156             resampleDesBuffer.resize(desSpanSize * desChannels, 0.f);
157         }
158         downMixer_ = std::make_unique<AudioDownMixStereo>();
159         int32_t ret = downMixer_->InitMixer(streamInfo.channelLayout, streamInfo.channels);
160         if (ret != SUCCESS) {
161             AUDIO_ERR_LOG("down mixer not supported.");
162             return ret;
163         }
164     }
165     uint32_t bufferSize = Util::GetSamplePerFrame(desFormat_) * desSpanSize * desChannels;
166     sinkBuffer_.resize(DEFAULT_TOTAL_SPAN_COUNT, std::vector<char>(bufferSize, 0));
167     for (int32_t i = 0; i < DEFAULT_TOTAL_SPAN_COUNT; i++) {
168         writeQueue_.emplace(i);
169     }
170     SetOffloadDisable();
171     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, DUMP_DIRECT_STREAM_FILE, &dumpFile_);
172     status_ = I_STATUS_IDLE;
173     return SUCCESS;
174 }
175 
Start()176 int32_t ProRendererStreamImpl::Start()
177 {
178     Trace trace("ProRendererStreamImpl::Start::" + std::to_string(streamIndex_));
179     isBlock_ = false;
180     AUDIO_INFO_LOG("Enter");
181     if (status_ == I_STATUS_INVALID) {
182         return ERR_ILLEGAL_STATE;
183     }
184     if (status_ == I_STATUS_STARTED) {
185         return SUCCESS;
186     }
187     status_ = I_STATUS_STARTED;
188     isFirstFrame_ = true;
189     isFirstNoUnderrunFrame_ = false;
190     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
191     if (statusCallback != nullptr) {
192         statusCallback->OnStatusUpdate(OPERATION_STARTED);
193     }
194     return SUCCESS;
195 }
196 
Pause(bool isStandby)197 int32_t ProRendererStreamImpl::Pause(bool isStandby)
198 {
199     Trace trace("ProRendererStreamImpl::Pause::" + std::to_string(streamIndex_));
200     AUDIO_INFO_LOG("Enter");
201     if (status_ == I_STATUS_STARTED) {
202         status_ = I_STATUS_PAUSED;
203     }
204     if (isFirstFrame_) {
205         firstFrameSync_.notify_all();
206     }
207     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
208     if (statusCallback != nullptr) {
209         statusCallback->OnStatusUpdate(OPERATION_PAUSED);
210     }
211     return SUCCESS;
212 }
213 
Flush()214 int32_t ProRendererStreamImpl::Flush()
215 {
216     Trace trace("ProRendererStreamImpl::Flush::" + std::to_string(streamIndex_));
217     AUDIO_INFO_LOG("reset total bytes");
218     {
219         std::lock_guard lock(enqueueMutex);
220         while (!readQueue_.empty()) {
221             int32_t index = readQueue_.front();
222             readQueue_.pop();
223             writeQueue_.emplace(index);
224         }
225         if (isDrain_) {
226             drainSync_.notify_all();
227         }
228     }
229     for (auto &buffer : sinkBuffer_) {
230         memset_s(buffer.data(), buffer.size(), 0, buffer.size());
231     }
232     sinkBytesWritten_ = 0;
233     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
234     if (statusCallback != nullptr) {
235         statusCallback->OnStatusUpdate(OPERATION_FLUSHED);
236     }
237     return SUCCESS;
238 }
239 
Drain(bool stopFlag)240 int32_t ProRendererStreamImpl::Drain(bool stopFlag)
241 {
242     Trace trace("ProRendererStreamImpl::Drain::" + std::to_string(streamIndex_));
243     AUDIO_INFO_LOG("Enter");
244     isDrain_ = true;
245     if (!readQueue_.empty()) {
246         std::unique_lock lock(enqueueMutex);
247         drainSync_.wait_for(lock, std::chrono::milliseconds(DRAIN_WAIT_TIMEOUT_TIME),
248             [this] { return readQueue_.empty(); });
249     }
250     isDrain_ = false;
251     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
252     if (statusCallback != nullptr) {
253         statusCallback->OnStatusUpdate(OPERATION_DRAINED);
254     }
255     status_ = I_STATUS_DRAINED;
256     return SUCCESS;
257 }
258 
Stop()259 int32_t ProRendererStreamImpl::Stop()
260 {
261     Trace trace("ProRendererStreamImpl::Stop::" + std::to_string(streamIndex_));
262     AUDIO_INFO_LOG("Enter");
263     status_ = I_STATUS_STOPPED;
264     if (isFirstFrame_) {
265         firstFrameSync_.notify_all();
266     }
267     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
268     if (statusCallback != nullptr) {
269         statusCallback->OnStatusUpdate(OPERATION_STOPPED);
270     }
271     return SUCCESS;
272 }
273 
Release()274 int32_t ProRendererStreamImpl::Release()
275 {
276     Trace trace("ProRendererStreamImpl::Release::" + std::to_string(streamIndex_));
277     AUDIO_INFO_LOG("Enter");
278     status_ = I_STATUS_INVALID;
279     isBlock_ = true;
280     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
281     if (statusCallback != nullptr) {
282         statusCallback->OnStatusUpdate(OPERATION_RELEASED);
283     }
284     return SUCCESS;
285 }
286 
GetStreamFramesWritten(uint64_t & framesWritten)287 int32_t ProRendererStreamImpl::GetStreamFramesWritten(uint64_t &framesWritten)
288 {
289     CHECK_AND_RETURN_RET_LOG(byteSizePerFrame_ != 0, ERR_ILLEGAL_STATE, "Error frame size");
290     framesWritten = totalBytesWritten_ / byteSizePerFrame_;
291     return SUCCESS;
292 }
293 
GetCurrentTimeStamp(uint64_t & timestamp)294 int32_t ProRendererStreamImpl::GetCurrentTimeStamp(uint64_t &timestamp)
295 {
296     int64_t timeSec = 0;
297     int64_t timeNsec = 0;
298     uint64_t framePosition;
299     bool ret = GetAudioTime(framePosition, timeSec, timeNsec);
300     CHECK_AND_RETURN_RET_LOG(ret, ERROR, "GetAudioTime error");
301     timestamp = static_cast<uint64_t>(timeSec * AUDIO_NS_PER_S + timeNsec);
302     return SUCCESS;
303 }
304 
GetCurrentPosition(uint64_t & framePosition,uint64_t & timestamp,uint64_t & latency)305 int32_t ProRendererStreamImpl::GetCurrentPosition(uint64_t &framePosition, uint64_t &timestamp, uint64_t &latency)
306 {
307     int64_t timeSec = 0;
308     int64_t timeNsec = 0;
309     bool ret = GetAudioTime(framePosition, timeSec, timeNsec);
310     CHECK_AND_RETURN_RET_LOG(ret, ERROR, "GetAudioTime error");
311     timespec tm {};
312     clock_gettime(CLOCK_MONOTONIC, &tm);
313     timestamp = static_cast<uint64_t>(tm.tv_sec) * AUDIO_NS_PER_S + static_cast<uint64_t>(tm.tv_nsec);
314     latency = 0;
315     return SUCCESS;
316 }
317 
GetLatency(uint64_t & latency)318 int32_t ProRendererStreamImpl::GetLatency(uint64_t &latency)
319 {
320     CHECK_AND_RETURN_RET_LOG(byteSizePerFrame_ != 0, ERR_ILLEGAL_STATE, "Error frame size");
321     uint64_t framePos = sinkBytesWritten_ / byteSizePerFrame_;
322     latency = ((framePos / byteSizePerFrame_) * AUDIO_US_PER_S) / processConfig_.streamInfo.samplingRate;
323     return SUCCESS;
324 }
325 
SetRate(int32_t rate)326 int32_t ProRendererStreamImpl::SetRate(int32_t rate)
327 {
328     uint32_t currentRate = processConfig_.streamInfo.samplingRate;
329     switch (rate) {
330         case RENDER_RATE_NORMAL:
331             break;
332         case RENDER_RATE_DOUBLE:
333             currentRate *= DOUBLE_VALUE;
334             break;
335         case RENDER_RATE_HALF:
336             currentRate /= DOUBLE_VALUE;
337             break;
338         default:
339             return ERR_INVALID_PARAM;
340     }
341     (void)currentRate;
342     renderRate_ = rate;
343     return SUCCESS;
344 }
345 
SetAudioEffectMode(int32_t effectMode)346 int32_t ProRendererStreamImpl::SetAudioEffectMode(int32_t effectMode)
347 {
348     return SUCCESS;
349 }
350 
GetAudioEffectMode(int32_t & effectMode)351 int32_t ProRendererStreamImpl::GetAudioEffectMode(int32_t &effectMode)
352 {
353     return SUCCESS;
354 }
355 
SetPrivacyType(int32_t privacyType)356 int32_t ProRendererStreamImpl::SetPrivacyType(int32_t privacyType)
357 {
358     privacyType_ = privacyType;
359     return SUCCESS;
360 }
361 
GetPrivacyType(int32_t & privacyType)362 int32_t ProRendererStreamImpl::GetPrivacyType(int32_t &privacyType)
363 {
364     privacyType = privacyType_;
365     return SUCCESS;
366 }
367 
RegisterStatusCallback(const std::weak_ptr<IStatusCallback> & callback)368 void ProRendererStreamImpl::RegisterStatusCallback(const std::weak_ptr<IStatusCallback> &callback)
369 {
370     AUDIO_DEBUG_LOG("enter in");
371     statusCallback_ = callback;
372 }
373 
RegisterWriteCallback(const std::weak_ptr<IWriteCallback> & callback)374 void ProRendererStreamImpl::RegisterWriteCallback(const std::weak_ptr<IWriteCallback> &callback)
375 {
376     AUDIO_DEBUG_LOG("enter in");
377     writeCallback_ = callback;
378 }
379 
DequeueBuffer(size_t length)380 BufferDesc ProRendererStreamImpl::DequeueBuffer(size_t length)
381 {
382     Trace trace("ProRendererStreamImpl::DequeueBuffer");
383     BufferDesc bufferDesc = {nullptr, 0, 0};
384     if (status_ != I_STATUS_STARTED) {
385         return bufferDesc;
386     }
387     bufferDesc.buffer = reinterpret_cast<uint8_t *>(sinkBuffer_[0].data());
388     bufferDesc.bufLength = sinkBuffer_[0].size();
389     return bufferDesc;
390 }
391 
EnqueueBuffer(const BufferDesc & bufferDesc)392 int32_t ProRendererStreamImpl::EnqueueBuffer(const BufferDesc &bufferDesc)
393 {
394     Trace trace("ProRendererStreamImpl::EnqueueBuffer::" + std::to_string(streamIndex_));
395     int32_t writeIndex = PopWriteBufferIndex();
396     if (writeIndex < 0) {
397         AUDIO_ERR_LOG("write index is empty.");
398         return ERR_WRITE_BUFFER;
399     }
400     std::lock_guard lock(peekMutex);
401     GetStreamVolume();
402     if (isNeedMcr_ && !isNeedResample_) {
403         ConvertSrcToFloat(bufferDesc);
404         downMixer_->Apply(spanSizeInFrame_, resampleSrcBuffer.data(), resampleDesBuffer.data());
405         ConvertFloatToDes(writeIndex);
406     } else if (isNeedMcr_ && isNeedResample_) {
407         ConvertSrcToFloat(bufferDesc);
408         downMixer_->Apply(spanSizeInFrame_, resampleSrcBuffer.data(), resampleSrcBuffer.data());
409     }
410     if (isNeedResample_) {
411         if (!isNeedMcr_) {
412             ConvertSrcToFloat(bufferDesc);
413         }
414         resample_->ProcessFloatResample(resampleSrcBuffer, resampleDesBuffer);
415         DumpFileUtil::WriteDumpFile(dumpFile_, resampleDesBuffer.data(), resampleDesBuffer.size() * sizeof(float));
416         ConvertFloatToDes(writeIndex);
417     } else if (!isNeedMcr_) {
418         bufferInfo_.bufLength = bufferDesc.bufLength;
419         bufferInfo_.frameSize = bufferDesc.bufLength / bufferInfo_.samplePerFrame;
420         bufferInfo_.buffer = bufferDesc.buffer;
421         if (desFormat_ == AudioSampleFormat::SAMPLE_S16LE) {
422             AudioCommonConverter::ConvertBufferTo16Bit(bufferInfo_, sinkBuffer_[writeIndex]);
423         } else {
424             AudioCommonConverter::ConvertBufferTo32Bit(bufferInfo_, sinkBuffer_[writeIndex]);
425         }
426     }
427     readQueue_.emplace(writeIndex);
428     if (isFirstFrame_) {
429         firstFrameSync_.notify_all();
430     }
431     AUDIO_DEBUG_LOG("buffer length:%{public}zu ,sink buffer length:%{public}zu", bufferDesc.bufLength,
432         sinkBuffer_[0].size());
433     totalBytesWritten_ += bufferDesc.bufLength;
434     sinkBytesWritten_ += bufferDesc.bufLength;
435     return SUCCESS;
436 }
437 
GetMinimumBufferSize(size_t & minBufferSize) const438 int32_t ProRendererStreamImpl::GetMinimumBufferSize(size_t &minBufferSize) const
439 {
440     minBufferSize = minBufferSize_;
441     return SUCCESS;
442 }
443 
GetByteSizePerFrame(size_t & byteSizePerFrame) const444 void ProRendererStreamImpl::GetByteSizePerFrame(size_t &byteSizePerFrame) const
445 {
446     byteSizePerFrame = byteSizePerFrame_;
447 }
448 
GetSpanSizePerFrame(size_t & spanSizeInFrame) const449 void ProRendererStreamImpl::GetSpanSizePerFrame(size_t &spanSizeInFrame) const
450 {
451     spanSizeInFrame = spanSizeInFrame_;
452 }
453 
SetStreamIndex(uint32_t index)454 void ProRendererStreamImpl::SetStreamIndex(uint32_t index)
455 {
456     AUDIO_INFO_LOG("Using index/sessionId %{public}d", index);
457     streamIndex_ = index;
458 }
459 
GetStreamIndex()460 uint32_t ProRendererStreamImpl::GetStreamIndex()
461 {
462     return streamIndex_;
463 }
464 
465 // offload
SetOffloadMode(int32_t state,bool isAppBack)466 int32_t ProRendererStreamImpl::SetOffloadMode(int32_t state, bool isAppBack)
467 {
468     SetOffloadDisable();
469     return SUCCESS;
470 }
471 
UnsetOffloadMode()472 int32_t ProRendererStreamImpl::UnsetOffloadMode()
473 {
474     SetOffloadDisable();
475     return SUCCESS;
476 }
477 
GetOffloadApproximatelyCacheTime(uint64_t & timestamp,uint64_t & paWriteIndex,uint64_t & cacheTimeDsp,uint64_t & cacheTimePa)478 int32_t ProRendererStreamImpl::GetOffloadApproximatelyCacheTime(uint64_t &timestamp, uint64_t &paWriteIndex,
479     uint64_t &cacheTimeDsp, uint64_t &cacheTimePa)
480 {
481     return SUCCESS;
482 }
483 
OffloadSetVolume(float volume)484 int32_t ProRendererStreamImpl::OffloadSetVolume(float volume)
485 {
486     return SUCCESS;
487 }
488 
GetWritableSize()489 size_t ProRendererStreamImpl::GetWritableSize()
490 {
491     return writeQueue_.size() * minBufferSize_;
492 }
493 // offload end
UpdateSpatializationState(bool spatializationEnabled,bool headTrackingEnabled)494 int32_t ProRendererStreamImpl::UpdateSpatializationState(bool spatializationEnabled, bool headTrackingEnabled)
495 {
496     return SUCCESS;
497 }
498 
GetAudioProcessConfig() const499 AudioProcessConfig ProRendererStreamImpl::GetAudioProcessConfig() const noexcept
500 {
501     return processConfig_;
502 }
503 
GetAudioTime(uint64_t & framePos,int64_t & sec,int64_t & nanoSec)504 bool ProRendererStreamImpl::GetAudioTime(uint64_t &framePos, int64_t &sec, int64_t &nanoSec)
505 {
506     GetStreamFramesWritten(framePos);
507     int64_t time = handleTimeModel_.GetTimeOfPos(framePos);
508     int64_t deltaTime = DEFAULT_BUFFER_MICROSECOND; // note: 20ms
509     time += deltaTime;
510     sec = time / AUDIO_NS_PER_S;
511     nanoSec = time % AUDIO_NS_PER_S;
512     return true;
513 }
514 
Peek(std::vector<char> * audioBuffer,int32_t & index)515 int32_t ProRendererStreamImpl::Peek(std::vector<char> *audioBuffer, int32_t &index)
516 {
517     Trace trace("ProRendererStreamImpl::Peek::" + std::to_string(streamIndex_));
518     int32_t result = SUCCESS;
519     if (isBlock_) {
520         return ERR_WRITE_BUFFER;
521     }
522     if (!readQueue_.empty()) {
523         PopSinkBuffer(audioBuffer, index);
524         return result;
525     }
526 
527     std::shared_ptr<IWriteCallback> writeCallback = writeCallback_.lock();
528     if (writeCallback != nullptr) {
529         result = writeCallback->OnWriteData(minBufferSize_);
530         switch (result) {
531             // As a low-risk change, temporarily keep the previous behavior
532             // and avoid enterring the err logic on underrun.
533             case ERR_RENDERER_IN_SERVER_UNDERRUN: {
534                 auto statusCallback = statusCallback_.lock();
535                 if (statusCallback != nullptr && isFirstNoUnderrunFrame_) {
536                     statusCallback->OnStatusUpdate(OPERATION_UNDERFLOW);
537                 }
538                 [[fallthrough]];
539             }
540             case SUCCESS: {
541                 PopSinkBuffer(audioBuffer, index);
542                 if (result != ERR_RENDERER_IN_SERVER_UNDERRUN) {
543                     isFirstNoUnderrunFrame_ = true;
544                     result = SUCCESS;
545                 }
546                 break;
547             }
548             default: {
549                 AUDIO_ERR_LOG("Write callback failed,result:%{public}d", result);
550                 return result;
551             }
552         }
553     } else {
554         AUDIO_ERR_LOG("Write callback is nullptr");
555         result = ERR_WRITE_BUFFER;
556     }
557     return result;
558 }
559 
ReturnIndex(int32_t index)560 int32_t ProRendererStreamImpl::ReturnIndex(int32_t index)
561 {
562     if (index < 0) {
563         return SUCCESS;
564     }
565     std::lock_guard lock(enqueueMutex);
566     writeQueue_.emplace(index);
567     return SUCCESS;
568 }
569 
SetClientVolume(float clientVolume)570 int32_t ProRendererStreamImpl::SetClientVolume(float clientVolume)
571 {
572     AUDIO_INFO_LOG("clientVolume: %{public}f", clientVolume);
573     return SUCCESS;
574 }
575 
UpdateMaxLength(uint32_t maxLength)576 int32_t ProRendererStreamImpl::UpdateMaxLength(uint32_t maxLength)
577 {
578     return SUCCESS;
579 }
580 
PopWriteBufferIndex()581 int32_t ProRendererStreamImpl::PopWriteBufferIndex()
582 {
583     std::lock_guard lock(enqueueMutex);
584     int32_t writeIndex = -1;
585     if (!writeQueue_.empty()) {
586         writeIndex = writeQueue_.front();
587         writeQueue_.pop();
588     }
589     return writeIndex;
590 }
591 
PopSinkBuffer(std::vector<char> * audioBuffer,int32_t & index)592 void ProRendererStreamImpl::PopSinkBuffer(std::vector<char> *audioBuffer, int32_t &index)
593 {
594     if (readQueue_.empty() && isFirstFrame_) {
595         std::unique_lock firstFrameLock(firstFrameMutex);
596         firstFrameSync_.wait_for(firstFrameLock, std::chrono::milliseconds(FIRST_FRAME_TIMEOUT_TIME),
597             [this] { return (!readQueue_.empty() || isBlock_); });
598         if (!readQueue_.empty()) {
599             isFirstFrame_ = false;
600         }
601     }
602     std::lock_guard lock(enqueueMutex);
603     if (!readQueue_.empty()) {
604         index = readQueue_.front();
605         readQueue_.pop();
606         *audioBuffer = sinkBuffer_[index];
607     }
608     if (readQueue_.empty() && isDrain_) {
609         drainSync_.notify_all();
610     }
611 }
612 
SetOffloadDisable()613 void ProRendererStreamImpl::SetOffloadDisable()
614 {
615     std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
616     if (statusCallback != nullptr) {
617         statusCallback->OnStatusUpdate(OPERATION_UNSET_OFFLOAD_ENABLE);
618     }
619 }
620 
ConvertSrcToFloat(const BufferDesc & bufferDesc)621 void ProRendererStreamImpl::ConvertSrcToFloat(const BufferDesc &bufferDesc)
622 {
623     bufferInfo_.buffer = bufferDesc.buffer;
624     bufferInfo_.bufLength = bufferDesc.bufLength;
625     bufferInfo_.frameSize = bufferDesc.bufLength / bufferInfo_.samplePerFrame;
626 
627     if (bufferInfo_.format == AudioSampleFormat::SAMPLE_F32LE) {
628         AudioCommonConverter::ConvertFloatToFloatWithVolume(bufferInfo_, resampleSrcBuffer);
629         return;
630     }
631     AUDIO_DEBUG_LOG("ConvertSrcToFloat resample buffer,samplePerFrame:%{public}d,size:%{public}zu",
632         bufferInfo_.samplePerFrame, resampleSrcBuffer.size());
633     AudioCommonConverter::ConvertBufferToFloat(bufferInfo_, resampleSrcBuffer);
634 }
635 
ConvertFloatToDes(int32_t writeIndex)636 void ProRendererStreamImpl::ConvertFloatToDes(int32_t writeIndex)
637 {
638     uint32_t samplePerFrame = Util::GetSamplePerFrame(desFormat_);
639     if (desFormat_ == AudioSampleFormat::SAMPLE_F32LE) {
640         auto error = memcpy_s(sinkBuffer_[writeIndex].data(), sinkBuffer_[writeIndex].size(), resampleDesBuffer.data(),
641             resampleDesBuffer.size() * samplePerFrame);
642         if (error != EOK) {
643             AUDIO_ERR_LOG("copy failed");
644         }
645         return;
646     }
647     AudioCommonConverter::ConvertFloatToAudioBuffer(resampleDesBuffer,
648         reinterpret_cast<uint8_t *>(sinkBuffer_[writeIndex].data()), samplePerFrame);
649 }
650 
GetStreamVolume()651 void ProRendererStreamImpl::GetStreamVolume()
652 {
653     if (processConfig_.streamType == STREAM_VOICE_COMMUNICATION) {
654         bufferInfo_.volumeBg = 1;
655         bufferInfo_.volumeEd = 1;
656         return;
657     }
658     AudioVolumeType volumeType = VolumeUtils::GetVolumeTypeFromStreamType(processConfig_.streamType);
659     bufferInfo_.volumeBg = AudioVolume::GetInstance()->GetHistoryVolume(streamIndex_);
660     bufferInfo_.volumeEd = AudioVolume::GetInstance()->GetVolume(streamIndex_, volumeType, DEVICE_NAME);
661     if (bufferInfo_.volumeBg != bufferInfo_.volumeEd) {
662         AudioVolume::GetInstance()->SetHistoryVolume(streamIndex_, bufferInfo_.volumeEd);
663         AudioVolume::GetInstance()->Monitor(streamIndex_, true);
664         AUDIO_INFO_LOG("audio volume begin:%{public}f,end:%{public}f", bufferInfo_.volumeBg, bufferInfo_.volumeEd);
665     }
666 }
667 
InitBasicInfo(const AudioStreamInfo & streamInfo)668 void ProRendererStreamImpl::InitBasicInfo(const AudioStreamInfo &streamInfo)
669 {
670     currentRate_ = streamInfo.samplingRate;
671     desSamplingRate_ = GetDirectSampleRate(streamInfo.samplingRate);
672     desFormat_ = GetDirectFormat(streamInfo.format);
673     spanSizeInFrame_ = (streamInfo.samplingRate * DEFAULT_BUFFER_MILLISECOND) / SECOND_TO_MILLISECOND;
674     byteSizePerFrame_ = Util::GetSamplePerFrame(streamInfo.format) * streamInfo.channels;
675     minBufferSize_ = spanSizeInFrame_ * byteSizePerFrame_;
676     handleTimeModel_.ConfigSampleRate(currentRate_);
677     bufferInfo_.channelCount = streamInfo.channels;
678     bufferInfo_.format = streamInfo.format;
679     bufferInfo_.samplePerFrame = Util::GetSamplePerFrame(streamInfo.format);
680     bufferInfo_.frameSize = spanSizeInFrame_;
681 }
682 
BlockStream()683 void ProRendererStreamImpl::BlockStream() noexcept
684 {
685     isBlock_ = true;
686     AudioVolume::GetInstance()->SetHistoryVolume(streamIndex_, 0.f);
687 }
688 } // namespace AudioStandard
689 } // namespace OHOS
690