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 ×tamp)
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 ×tamp, 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 ×tamp, 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