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