• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "AudioProcessInClientInner"
17 #endif
18 
19 #include "audio_process_in_client.h"
20 
21 #include <atomic>
22 #include <cinttypes>
23 #include <condition_variable>
24 #include <sstream>
25 #include <string>
26 #include <mutex>
27 #include <thread>
28 
29 #include "iservice_registry.h"
30 #include "system_ability_definition.h"
31 
32 #include "audio_errors.h"
33 #include "audio_capturer_log.h"
34 #include "audio_system_manager.h"
35 #include "audio_utils.h"
36 #include "securec.h"
37 
38 #include "audio_manager_base.h"
39 #include "audio_process_cb_stub.h"
40 #include "audio_server_death_recipient.h"
41 #include "fast_audio_stream.h"
42 #include "i_audio_process.h"
43 #include "linear_pos_time_model.h"
44 #include "volume_tools.h"
45 #include "format_converter.h"
46 
47 namespace OHOS {
48 namespace AudioStandard {
49 
50 namespace {
51 static constexpr int32_t VOLUME_SHIFT_NUMBER = 16; // 1 >> 16 = 65536, max volume
52 static const int64_t DELAY_RESYNC_TIME = 10000000000; // 10s
53 constexpr int32_t RETRY_WAIT_TIME_MS = 500; // 500ms
54 constexpr int32_t MAX_RETRY_COUNT = 8;
55 }
56 
57 class ProcessCbImpl;
58 class AudioProcessInClientInner : public AudioProcessInClient,
59     public std::enable_shared_from_this<AudioProcessInClientInner> {
60 public:
61     AudioProcessInClientInner(const sptr<IAudioProcess> &ipcProxy, bool isVoipMmap);
62     ~AudioProcessInClientInner();
63 
64     int32_t SaveDataCallback(const std::shared_ptr<AudioDataCallback> &dataCallback) override;
65 
66     int32_t SaveUnderrunCallback(const std::shared_ptr<ClientUnderrunCallBack> &underrunCallback) override;
67 
68     int32_t GetBufferDesc(BufferDesc &bufDesc) const override;
69 
70     int32_t Enqueue(const BufferDesc &bufDesc) const override;
71 
72     int32_t SetVolume(int32_t vol) override;
73 
74     int32_t Start() override;
75 
76     int32_t Pause(bool isFlush) override;
77 
78     int32_t Resume() override;
79 
80     int32_t Stop() override;
81 
82     int32_t Release(bool isSwitchStream = false) override;
83 
84     // methods for support IAudioStream
85     int32_t GetSessionID(uint32_t &sessionID) override;
86 
87     bool GetAudioTime(uint32_t &framePos, int64_t &sec, int64_t &nanoSec) override;
88 
89     int32_t GetBufferSize(size_t &bufferSize) override;
90 
91     int32_t GetFrameCount(uint32_t &frameCount) override;
92 
93     int32_t GetLatency(uint64_t &latency) override;
94 
95     int32_t SetVolume(float vol) override;
96 
97     float GetVolume() override;
98 
99     int32_t SetDuckVolume(float vol) override;
100 
101     int32_t SetMute(bool mute) override;
102 
103     int32_t SetSourceDuration(int64_t duration) override;
104 
105     uint32_t GetUnderflowCount() override;
106 
107     uint32_t GetOverflowCount() override;
108 
109     void SetUnderflowCount(uint32_t underflowCount) override;
110 
111     void SetOverflowCount(uint32_t overflowCount) override;
112 
113     int64_t GetFramesWritten() override;
114 
115     int64_t GetFramesRead() override;
116 
117     void SetPreferredFrameSize(int32_t frameSize) override;
118 
119     void UpdateLatencyTimestamp(std::string &timestamp, bool isRenderer) override;
120 
121     bool Init(const AudioProcessConfig &config, std::weak_ptr<FastAudioStream> weakStream);
122 
123     int32_t SetDefaultOutputDevice(const DeviceType defaultOutputDevice) override;
124 
125     int32_t SetSilentModeAndMixWithOthers(bool on) override;
126 
127     void GetRestoreInfo(RestoreInfo &restoreInfo) override;
128 
129     void SetRestoreInfo(RestoreInfo &restoreInfo) override;
130 
131     RestoreStatus CheckRestoreStatus() override;
132 
133     RestoreStatus SetRestoreStatus(RestoreStatus restoreStatus) override;
134 
135     static const sptr<IStandardAudioService> GetAudioServerProxy();
136     static void AudioServerDied(pid_t pid, pid_t uid);
137     static constexpr AudioStreamInfo g_targetStreamInfo = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO};
138 
139 private:
140     // move it to a common folder
141     static bool ChannelFormatConvert(const AudioStreamData &srcData, const AudioStreamData &dstData);
142 
143     bool InitAudioBuffer();
144     void ResetAudioBuffer();
145 
146     bool PrepareCurrent(uint64_t curWritePos);
147     void CallClientHandleCurrent();
148     bool FinishHandleCurrent(uint64_t &curWritePos, int64_t &clientWriteCost);
149     int32_t ReadFromProcessClient() const;
150     int32_t RecordReSyncServicePos();
151     int32_t RecordPrepareCurrent(uint64_t curReadPos);
152     int32_t RecordFinishHandleCurrent(uint64_t &curReadPos, int64_t &clientReadCost);
153     bool PrepareCurrentLoop(uint64_t curWritePos);
154     bool FinishHandleCurrentLoop(uint64_t &curWritePos, int64_t &clientWriteCost);
155 
156     void UpdateHandleInfo(bool isAysnc = true, bool resetReadWritePos = false);
157     int64_t GetPredictNextHandleTime(uint64_t posInFrame, bool isIndependent = false);
158     bool PrepareNext(uint64_t curHandPos, int64_t &wakeUpTime);
159     bool ClientPrepareNextLoop(uint64_t curWritePos, int64_t &wakeUpTime);
160     bool PrepareNextIndependent(uint64_t curWritePos, int64_t &wakeUpTime);
161 
162     std::string GetStatusInfo(StreamStatus status);
163     bool KeepLoopRunning();
164     bool KeepLoopRunningIndependent();
165 
166     void CallExitStandBy();
167 
168     bool ProcessCallbackFuc(uint64_t &curWritePos, int64_t &curTime, int64_t &wakeUpTime, int64_t &clientWriteCost);
169     void ProcessCallbackFucIndependent();
170     bool RecordProcessCallbackFuc(uint64_t &curReadPos, int64_t &wakeUpTime, int64_t clientReadCost);
171     void InitPlaybackThread(std::weak_ptr<FastAudioStream> weakStream);
172     void InitRecordThread(std::weak_ptr<FastAudioStream> weakStream);
173     void CopyWithVolume(const BufferDesc &srcDesc, const BufferDesc &dstDesc) const;
174     void ProcessVolume(const AudioStreamData &targetData) const;
175     int32_t ProcessData(const BufferDesc &srcDesc, const BufferDesc &dstDesc) const;
176     void CheckIfWakeUpTooLate(int64_t &curTime, int64_t &wakeUpTime);
177     void CheckIfWakeUpTooLate(int64_t &curTime, int64_t &wakeUpTime, int64_t clientWriteCost);
178 
179     void DoFadeInOut(uint64_t &curWritePos);
180 
181 private:
182     static constexpr int64_t MILLISECOND_PER_SECOND = 1000; // 1000ms
183     static constexpr int64_t ONE_MILLISECOND_DURATION = 1000000; // 1ms
184     static constexpr int64_t TWO_MILLISECOND_DURATION = 2000000; // 2ms
185     static constexpr int64_t VOIP_MILLISECOND_DURATION = 20000000; // 20ms
186     static constexpr int64_t MAX_WRITE_COST_DURATION_NANO = 5000000; // 5ms
187     static constexpr int64_t MAX_READ_COST_DURATION_NANO = 5000000; // 5ms
188     static constexpr int64_t WRITE_BEFORE_DURATION_NANO = 2000000; // 2ms
189     static constexpr int64_t RECORD_RESYNC_SLEEP_NANO = 2000000; // 2ms
190     static constexpr int64_t RECORD_HANDLE_DELAY_NANO = 3000000; // 3ms
191     static constexpr size_t MAX_TIMES = 4; // 4 times spanSizeInFrame_
192     static constexpr size_t DIV = 2; // halt of span
193     static constexpr int64_t MAX_STOP_FADING_DURATION_NANO = 10000000; // 10ms
194     static constexpr int64_t WAKE_UP_LATE_COUNT = 20; // late for 20 times
195     enum ThreadStatus : uint32_t {
196         WAITTING = 0,
197         SLEEPING,
198         INRUNNING,
199         INVALID
200     };
201     AudioProcessConfig processConfig_;
202     bool needConvert_ = false;
203     size_t clientByteSizePerFrame_ = 0;
204     size_t clientSpanSizeInByte_ = 0;
205     size_t clientSpanSizeInFrame_ = 240;
206     sptr<IAudioProcess> processProxy_ = nullptr;
207     std::shared_ptr<OHAudioBuffer> audioBuffer_ = nullptr;
208     uint32_t sessionId_ = 0;
209     bool isVoipMmap_ = false;
210 
211     uint32_t totalSizeInFrame_ = 0;
212     uint32_t spanSizeInFrame_ = 0;
213     uint32_t byteSizePerFrame_ = 0;
214     uint32_t spanSizeInMs_ = 0;
215     size_t spanSizeInByte_ = 0;
216     std::weak_ptr<AudioDataCallback> audioDataCallback_;
217     std::weak_ptr<ClientUnderrunCallBack> underrunCallback_;
218 
219     std::unique_ptr<uint8_t[]> callbackBuffer_ = nullptr;
220 
221     std::mutex statusSwitchLock_;
222     std::atomic<StreamStatus> *streamStatus_ = nullptr;
223     bool isInited_ = false;
224     bool needReSyncPosition_ = true;
225     int64_t lastPausedTime_ = INT64_MAX;
226 
227     float volumeInFloat_ = 1.0f;
228     float duckVolumeInFloat_ = 1.0f;
229     float muteVolumeInFloat_ = 1.0f;
230     int32_t processVolume_ = PROCESS_VOLUME_MAX; // 0 ~ 65536
231     LinearPosTimeModel handleTimeModel_;
232 
233     std::thread callbackLoop_; // thread for callback to client and write.
234     bool isCallbackLoopEnd_ = false;
235     std::atomic<ThreadStatus> threadStatus_ = INVALID;
236     std::mutex loopThreadLock_;
237     std::condition_variable threadStatusCV_;
238 
239     std::atomic<uint32_t> underflowCount_ = 0;
240     std::atomic<uint32_t> overflowCount_ = 0;
241 
242     FILE *dumpFile_ = nullptr;
243     mutable int64_t volumeDataCount_ = 0;
244     std::string logUtilsTag_ = "";
245 
246     std::atomic<bool> startFadein_ = false; // true-fade  in  when start or resume stream
247     std::atomic<bool> startFadeout_ = false; // true-fade out when pause or stop stream
248 
249     sptr<ProcessCbImpl> processCbImpl_ = nullptr;
250 };
251 
252 // ProcessCbImpl --> sptr | AudioProcessInClientInner --> shared_ptr
253 class ProcessCbImpl : public ProcessCbStub {
254 public:
255     explicit ProcessCbImpl(std::shared_ptr<AudioProcessInClientInner> processInClientInner);
256     virtual ~ProcessCbImpl() = default;
257 
258     int32_t OnEndpointChange(int32_t status) override;
259 
260 private:
261     std::weak_ptr<AudioProcessInClientInner> processInClientInner_;
262 };
263 
ProcessCbImpl(std::shared_ptr<AudioProcessInClientInner> processInClientInner)264 ProcessCbImpl::ProcessCbImpl(std::shared_ptr<AudioProcessInClientInner> processInClientInner)
265 {
266     if (processInClientInner == nullptr) {
267         AUDIO_ERR_LOG("ProcessCbImpl() find null processInClientInner");
268     }
269     processInClientInner_ = processInClientInner;
270 }
271 
OnEndpointChange(int32_t status)272 int32_t ProcessCbImpl::OnEndpointChange(int32_t status)
273 {
274     AUDIO_INFO_LOG("OnEndpointChange: %{public}d", status);
275     return SUCCESS;
276 }
277 
278 std::mutex g_audioServerProxyMutex;
279 sptr<IStandardAudioService> gAudioServerProxy = nullptr;
280 
AudioProcessInClientInner(const sptr<IAudioProcess> & ipcProxy,bool isVoipMmap)281 AudioProcessInClientInner::AudioProcessInClientInner(const sptr<IAudioProcess> &ipcProxy,
282     bool isVoipMmap) : processProxy_(ipcProxy), isVoipMmap_(isVoipMmap)
283 {
284     processProxy_->GetSessionId(sessionId_);
285     AUDIO_INFO_LOG("Construct with sessionId: %{public}d", sessionId_);
286 }
287 
GetAudioServerProxy()288 const sptr<IStandardAudioService> AudioProcessInClientInner::GetAudioServerProxy()
289 {
290     std::lock_guard<std::mutex> lock(g_audioServerProxyMutex);
291     if (gAudioServerProxy == nullptr) {
292         auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
293         CHECK_AND_RETURN_RET_LOG(samgr != nullptr, nullptr, "get sa manager failed");
294         sptr<IRemoteObject> object = samgr->GetSystemAbility(AUDIO_DISTRIBUTED_SERVICE_ID);
295         CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "get audio service remote object failed");
296         gAudioServerProxy = iface_cast<IStandardAudioService>(object);
297         CHECK_AND_RETURN_RET_LOG(gAudioServerProxy != nullptr, nullptr, "get audio service proxy failed");
298 
299         // register death recipent to restore proxy
300         sptr<AudioServerDeathRecipient> asDeathRecipient =
301             new(std::nothrow) AudioServerDeathRecipient(getpid(), getuid());
302         if (asDeathRecipient != nullptr) {
303             asDeathRecipient->SetNotifyCb([] (pid_t pid, pid_t uid) { AudioServerDied(pid, uid); });
304             bool result = object->AddDeathRecipient(asDeathRecipient);
305             if (!result) {
306                 AUDIO_WARNING_LOG("failed to add deathRecipient");
307             }
308         }
309     }
310     sptr<IStandardAudioService> gasp = gAudioServerProxy;
311     return gasp;
312 }
313 
314 /**
315  * When AudioServer died, all stream in client should be notified. As they were proxy stream ,the stub stream
316  * has been destoried in server.
317 */
AudioServerDied(pid_t pid,pid_t uid)318 void AudioProcessInClientInner::AudioServerDied(pid_t pid, pid_t uid)
319 {
320     AUDIO_INFO_LOG("audio server died, will restore proxy in next call");
321     std::lock_guard<std::mutex> lock(g_audioServerProxyMutex);
322     gAudioServerProxy = nullptr;
323 }
324 
Create(const AudioProcessConfig & config,std::weak_ptr<FastAudioStream> weakStream)325 std::shared_ptr<AudioProcessInClient> AudioProcessInClient::Create(const AudioProcessConfig &config,
326     std::weak_ptr<FastAudioStream> weakStream)
327 {
328     AUDIO_INFO_LOG("Create with config: render flag %{public}d, capturer flag %{public}d, streamType %{public}d.",
329         config.rendererInfo.rendererFlags, config.capturerInfo.capturerFlags, config.streamType);
330     bool ret = AudioProcessInClient::CheckIfSupport(config);
331     CHECK_AND_RETURN_RET_LOG(config.audioMode != AUDIO_MODE_PLAYBACK || ret, nullptr,
332         "CheckIfSupport failed!");
333     sptr<IStandardAudioService> gasp = AudioProcessInClientInner::GetAudioServerProxy();
334     CHECK_AND_RETURN_RET_LOG(gasp != nullptr, nullptr, "Create failed, can not get service.");
335     AudioProcessConfig resetConfig = config;
336     bool isVoipMmap = false;
337     if (config.rendererInfo.streamUsage != STREAM_USAGE_VOICE_COMMUNICATION &&
338         config.capturerInfo.sourceType != SOURCE_TYPE_VOICE_COMMUNICATION) {
339         resetConfig.streamInfo = AudioProcessInClientInner::g_targetStreamInfo;
340         if (config.audioMode == AUDIO_MODE_RECORD) {
341             resetConfig.streamInfo.format = config.streamInfo.format;
342             resetConfig.streamInfo.channels = config.streamInfo.channels;
343         }
344     } else {
345         isVoipMmap = true;
346     }
347 
348     int32_t errorCode = 0;
349     sptr<IRemoteObject> ipcProxy = gasp->CreateAudioProcess(resetConfig, errorCode);
350     for (int32_t retrycount = 0; (errorCode == ERR_RETRY_IN_CLIENT) && (retrycount < MAX_RETRY_COUNT); retrycount++) {
351         AUDIO_WARNING_LOG("retry in client");
352         std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_WAIT_TIME_MS));
353         ipcProxy = gasp->CreateAudioProcess(config, errorCode);
354     }
355     CHECK_AND_RETURN_RET_LOG(errorCode == SUCCESS, nullptr, "failed with create audio stream fail.");
356     CHECK_AND_RETURN_RET_LOG(ipcProxy != nullptr, nullptr, "Create failed with null ipcProxy.");
357     sptr<IAudioProcess> iProcessProxy = iface_cast<IAudioProcess>(ipcProxy);
358     CHECK_AND_RETURN_RET_LOG(iProcessProxy != nullptr, nullptr, "Create failed when iface_cast.");
359     std::shared_ptr<AudioProcessInClientInner> process =
360         std::make_shared<AudioProcessInClientInner>(iProcessProxy, isVoipMmap);
361     if (!process->Init(config, weakStream)) {
362         AUDIO_ERR_LOG("Init failed!");
363         process = nullptr;
364     }
365 
366     return process;
367 }
368 
~AudioProcessInClientInner()369 AudioProcessInClientInner::~AudioProcessInClientInner()
370 {
371     AUDIO_INFO_LOG("AudioProcessInClient deconstruct.");
372     if (callbackLoop_.joinable()) {
373         std::unique_lock<std::mutex> lock(loopThreadLock_);
374         isCallbackLoopEnd_ = true; // change it with lock to break the loop
375         threadStatusCV_.notify_all();
376         lock.unlock(); // should call unlock before join
377         callbackLoop_.detach();
378     }
379     if (isInited_) {
380         AudioProcessInClientInner::Release();
381     }
382     DumpFileUtil::CloseDumpFile(&dumpFile_);
383     AUDIO_INFO_LOG("[%{public}s] volume data counts: %{public}" PRId64, logUtilsTag_.c_str(), volumeDataCount_);
384 }
385 
GetSessionID(uint32_t & sessionID)386 int32_t AudioProcessInClientInner::GetSessionID(uint32_t &sessionID)
387 {
388     sessionID = sessionId_;
389     return SUCCESS;
390 }
391 
GetAudioTime(uint32_t & framePos,int64_t & sec,int64_t & nanoSec)392 bool AudioProcessInClientInner::GetAudioTime(uint32_t &framePos, int64_t &sec, int64_t &nanoSec)
393 {
394     CHECK_AND_RETURN_RET_LOG(audioBuffer_ != nullptr, false, "buffer is null, maybe not inited.");
395     uint64_t pos = 0;
396     if (processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
397         pos = audioBuffer_->GetCurWriteFrame();
398     } else {
399         pos = audioBuffer_->GetCurReadFrame();
400     }
401 
402     if (pos > UINT32_MAX) {
403         framePos = pos % UINT32_MAX;
404     } else {
405         framePos = static_cast<uint32_t>(pos);
406     }
407     int64_t time = handleTimeModel_.GetTimeOfPos(pos);
408     int64_t deltaTime = 20000000; // note: 20ms
409     time += deltaTime;
410 
411     sec = time / AUDIO_NS_PER_SECOND;
412     nanoSec = time % AUDIO_NS_PER_SECOND;
413     return true;
414 }
415 
GetBufferSize(size_t & bufferSize)416 int32_t AudioProcessInClientInner::GetBufferSize(size_t &bufferSize)
417 {
418     bufferSize = clientSpanSizeInByte_;
419     return SUCCESS;
420 }
421 
GetFrameCount(uint32_t & frameCount)422 int32_t AudioProcessInClientInner::GetFrameCount(uint32_t &frameCount)
423 {
424     frameCount = static_cast<uint32_t>(clientSpanSizeInFrame_);
425     AUDIO_INFO_LOG ("GetFrameCount successfully, FrameCount: %{public}u", frameCount);
426     return SUCCESS;
427 }
428 
GetLatency(uint64_t & latency)429 int32_t AudioProcessInClientInner::GetLatency(uint64_t &latency)
430 {
431     latency = 20; // 20ms for debug
432     return SUCCESS;
433 }
434 
SetVolume(float vol)435 int32_t AudioProcessInClientInner::SetVolume(float vol)
436 {
437     float minVol = 0.0f;
438     float maxVol = 1.0f;
439     CHECK_AND_RETURN_RET_LOG(vol >= minVol && vol <= maxVol, ERR_INVALID_PARAM,
440         "SetVolume failed to with invalid volume:%{public}f", vol);
441     int32_t volumeInt = static_cast<int32_t>(vol * PROCESS_VOLUME_MAX);
442     int32_t ret = SetVolume(volumeInt);
443     if (ret == SUCCESS) {
444         volumeInFloat_ = vol;
445     }
446     return ret;
447 }
448 
GetVolume()449 float AudioProcessInClientInner::GetVolume()
450 {
451     return volumeInFloat_;
452 }
453 
SetMute(bool mute)454 int32_t AudioProcessInClientInner::SetMute(bool mute)
455 {
456     muteVolumeInFloat_ = mute ? 0.0f : 1.0f;
457     return SUCCESS;
458 }
459 
SetSourceDuration(int64_t duration)460 int32_t AudioProcessInClientInner::SetSourceDuration(int64_t duration)
461 {
462     CHECK_AND_RETURN_RET_LOG(processProxy_ != nullptr, ERR_OPERATION_FAILED, "ipcProxy is null.");
463     return processProxy_->SetSourceDuration(duration);
464 }
465 
SetDuckVolume(float vol)466 int32_t AudioProcessInClientInner::SetDuckVolume(float vol)
467 {
468     float minVol = 0.0f;
469     float maxVol = 1.0f;
470     CHECK_AND_RETURN_RET_LOG(vol >= minVol && vol <= maxVol, ERR_INVALID_PARAM,
471         "SetDuckVolume failed to with invalid volume:%{public}f", vol);
472     duckVolumeInFloat_ = vol;
473     return SUCCESS;
474 }
475 
GetUnderflowCount()476 uint32_t AudioProcessInClientInner::GetUnderflowCount()
477 {
478     return underflowCount_.load();
479 }
480 
GetOverflowCount()481 uint32_t AudioProcessInClientInner::GetOverflowCount()
482 {
483     return overflowCount_.load();
484 }
485 
SetUnderflowCount(uint32_t underflowCount)486 void AudioProcessInClientInner::SetUnderflowCount(uint32_t underflowCount)
487 {
488     underflowCount_ += underflowCount;
489 }
490 
SetOverflowCount(uint32_t overflowCount)491 void AudioProcessInClientInner::SetOverflowCount(uint32_t overflowCount)
492 {
493     overflowCount_ += overflowCount;
494 }
495 
GetFramesWritten()496 int64_t AudioProcessInClientInner::GetFramesWritten()
497 {
498     CHECK_AND_RETURN_RET_LOG(processConfig_.audioMode == AUDIO_MODE_PLAYBACK, -1, "Playback not support.");
499     CHECK_AND_RETURN_RET_LOG(audioBuffer_ != nullptr, -1, "buffer is null, maybe not inited.");
500     return audioBuffer_->GetCurWriteFrame();
501 }
502 
GetFramesRead()503 int64_t AudioProcessInClientInner::GetFramesRead()
504 {
505     CHECK_AND_RETURN_RET_LOG(processConfig_.audioMode == AUDIO_MODE_RECORD, -1, "Record not support.");
506     CHECK_AND_RETURN_RET_LOG(audioBuffer_ != nullptr, -1, "buffer is null, maybe not inited.");
507     return audioBuffer_->GetCurReadFrame();
508 }
509 
SetPreferredFrameSize(int32_t frameSize)510 void AudioProcessInClientInner::SetPreferredFrameSize(int32_t frameSize)
511 {
512     size_t originalSpanSizeInFrame = static_cast<size_t>(spanSizeInFrame_);
513     size_t tmp = static_cast<size_t>(frameSize);
514     size_t count = static_cast<size_t>(frameSize) / spanSizeInFrame_;
515     size_t rest = static_cast<size_t>(frameSize) % spanSizeInFrame_;
516     if (tmp <= originalSpanSizeInFrame) {
517         clientSpanSizeInFrame_ = originalSpanSizeInFrame;
518     } else if (tmp >= MAX_TIMES * originalSpanSizeInFrame) {
519         clientSpanSizeInFrame_ = MAX_TIMES * originalSpanSizeInFrame;
520     } else {
521         if (rest <= originalSpanSizeInFrame / DIV) {
522             clientSpanSizeInFrame_ = count * spanSizeInFrame_;
523         } else {
524             count++;
525             clientSpanSizeInFrame_ = count * spanSizeInFrame_;
526         }
527     }
528     if (clientByteSizePerFrame_ == 0) {
529         clientSpanSizeInByte_ = count * spanSizeInByte_;
530     } else {
531         clientSpanSizeInByte_ = clientSpanSizeInFrame_ * clientByteSizePerFrame_;
532     }
533     callbackBuffer_ = std::make_unique<uint8_t[]>(clientSpanSizeInByte_);
534     AUDIO_INFO_LOG("Set preferred callbackBuffer size:%{public}zu", clientSpanSizeInByte_);
535     memset_s(callbackBuffer_.get(), clientSpanSizeInByte_, 0, clientSpanSizeInByte_);
536 }
537 
UpdateLatencyTimestamp(std::string & timestamp,bool isRenderer)538 void AudioProcessInClientInner::UpdateLatencyTimestamp(std::string &timestamp, bool isRenderer)
539 {
540     sptr<IStandardAudioService> gasp = AudioProcessInClientInner::GetAudioServerProxy();
541     if (gasp == nullptr) {
542         AUDIO_ERR_LOG("LatencyMeas failed to get AudioServerProxy");
543         return;
544     }
545     gasp->UpdateLatencyTimestamp(timestamp, isRenderer);
546 }
547 
InitAudioBuffer()548 bool AudioProcessInClientInner::InitAudioBuffer()
549 {
550     CHECK_AND_RETURN_RET_LOG(processProxy_ != nullptr, false, "Init failed with null ipcProxy.");
551     processCbImpl_ = sptr<ProcessCbImpl>::MakeSptr(shared_from_this());
552     CHECK_AND_RETURN_RET_LOG(processProxy_->RegisterProcessCb(processCbImpl_) == SUCCESS, false,
553         "RegisterProcessCb failed.");
554 
555     int32_t ret = processProxy_->ResolveBuffer(audioBuffer_);
556     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && audioBuffer_ != nullptr, false,
557         "Init failed to call ResolveBuffer");
558     streamStatus_ = audioBuffer_->GetStreamStatus();
559     CHECK_AND_RETURN_RET_LOG(streamStatus_ != nullptr, false, "Init failed, access buffer failed.");
560 
561     audioBuffer_->GetSizeParameter(totalSizeInFrame_, spanSizeInFrame_, byteSizePerFrame_);
562     spanSizeInByte_ = spanSizeInFrame_ * byteSizePerFrame_;
563     spanSizeInMs_ = spanSizeInFrame_ * MILLISECOND_PER_SECOND / processConfig_.streamInfo.samplingRate;
564 
565     clientSpanSizeInByte_ = spanSizeInFrame_ * clientByteSizePerFrame_;
566     clientSpanSizeInFrame_ = spanSizeInFrame_;
567     if ((processConfig_.audioMode != AUDIO_MODE_PLAYBACK) && (!isVoipMmap_)) {
568         clientSpanSizeInByte_ = spanSizeInByte_;
569     }
570 
571     AUDIO_INFO_LOG("Using totalSizeInFrame_ %{public}d spanSizeInFrame_ %{public}d byteSizePerFrame_ %{public}d "
572         "spanSizeInByte_ %{public}zu, spanSizeInMs_ %{public}u", totalSizeInFrame_, spanSizeInFrame_,
573         byteSizePerFrame_, spanSizeInByte_, spanSizeInMs_);
574 
575     callbackBuffer_ = std::make_unique<uint8_t[]>(clientSpanSizeInByte_);
576     CHECK_AND_RETURN_RET_LOG(callbackBuffer_ != nullptr, false, "Init callbackBuffer_ failed.");
577     memset_s(callbackBuffer_.get(), clientSpanSizeInByte_, 0, clientSpanSizeInByte_);
578     AUDIO_INFO_LOG("CallbackBufferSize is %{public}zu", clientSpanSizeInByte_);
579 
580     return true;
581 }
582 
GetFormatSize(const AudioStreamInfo & info)583 static size_t GetFormatSize(const AudioStreamInfo &info)
584 {
585     size_t result = 0;
586     size_t bitWidthSize = 0;
587     switch (info.format) {
588         case SAMPLE_U8:
589             bitWidthSize = 1; // size is 1
590             break;
591         case SAMPLE_S16LE:
592             bitWidthSize = 2; // size is 2
593             break;
594         case SAMPLE_S24LE:
595             bitWidthSize = 3; // size is 3
596             break;
597         case SAMPLE_S32LE:
598             bitWidthSize = 4; // size is 4
599             break;
600         case SAMPLE_F32LE:
601             bitWidthSize = 4; // size is 4
602             break;
603         default:
604             bitWidthSize = 2; // size is 2
605             break;
606     }
607 
608     size_t channelSize = 0;
609     switch (info.channels) {
610         case MONO:
611             channelSize = 1; // size is 1
612             break;
613         case STEREO:
614             channelSize = 2; // size is 2
615             break;
616         default:
617             channelSize = 2; // size is 2
618             break;
619     }
620     result = bitWidthSize * channelSize;
621     return result;
622 }
623 
InitPlaybackThread(std::weak_ptr<FastAudioStream> weakStream)624 void AudioProcessInClientInner::InitPlaybackThread(std::weak_ptr<FastAudioStream> weakStream)
625 {
626     logUtilsTag_ = "ProcessPlay::" + std::to_string(sessionId_);
627     auto weakProcess = weak_from_this();
628     callbackLoop_ = std::thread([weakStream, weakProcess] {
629         bool keepRunning = true;
630         uint64_t curWritePos = 0;
631         int64_t curTime = 0;
632         int64_t wakeUpTime = ClockTime::GetCurNano();
633         int64_t clientWriteCost = 0;
634         std::shared_ptr<AudioProcessInClientInner> strongProcess = weakProcess.lock();
635         std::shared_ptr<FastAudioStream> strongStream = weakStream.lock();
636         if (strongProcess != nullptr) {
637             AUDIO_INFO_LOG("Callback loop of session %{public}u start", strongProcess->sessionId_);
638             strongProcess->processProxy_->RegisterThreadPriority(gettid(),
639                 AudioSystemManager::GetInstance()->GetSelfBundleName(strongProcess->processConfig_.appInfo.appUid));
640         } else {
641             AUDIO_WARNING_LOG("Strong ref is nullptr, could cause error");
642         }
643         strongProcess = nullptr;
644         // Callback loop
645         while (keepRunning) {
646             strongStream = weakStream.lock();
647             strongProcess = weakProcess.lock();
648             // Check if FastAudioStream or AudioProcessInClientInner is already destroyed to avoid use after free.
649             CHECK_AND_BREAK_LOG(strongStream != nullptr, "FastAudioStream destroyed, exit AudioPlayCb");
650             CHECK_AND_BREAK_LOG(strongProcess != nullptr, "AudioProcessInClientInner destroyed, exit AudioPlayCb");
651             // Main operation in callback loop
652             keepRunning = strongProcess->ProcessCallbackFuc(curWritePos, curTime, wakeUpTime, clientWriteCost);
653         }
654         if (strongProcess != nullptr) {
655             AUDIO_INFO_LOG("Callback loop of session %{public}u end", strongProcess->sessionId_);
656         }
657     });
658     pthread_setname_np(callbackLoop_.native_handle(), "OS_AudioPlayCb");
659 }
660 
InitRecordThread(std::weak_ptr<FastAudioStream> weakStream)661 void AudioProcessInClientInner::InitRecordThread(std::weak_ptr<FastAudioStream> weakStream)
662 {
663     logUtilsTag_ = "ProcessRec::" + std::to_string(sessionId_);
664     auto weakProcess = weak_from_this();
665     callbackLoop_ = std::thread([weakStream, weakProcess] {
666         bool keepRunning = true;
667         uint64_t curReadPos = 0;
668         int64_t wakeUpTime = ClockTime::GetCurNano();
669         int64_t clientReadCost = 0;
670         std::shared_ptr<AudioProcessInClientInner> strongProcess = weakProcess.lock();
671         std::shared_ptr<FastAudioStream> strongStream = weakStream.lock();
672         if (strongProcess != nullptr) {
673             AUDIO_INFO_LOG("Callback loop of session %{public}u start", strongProcess->sessionId_);
674             strongProcess->processProxy_->RegisterThreadPriority(gettid(),
675                 AudioSystemManager::GetInstance()->GetSelfBundleName(strongProcess->processConfig_.appInfo.appUid));
676         } else {
677             AUDIO_WARNING_LOG("Strong ref is nullptr, could cause error");
678         }
679         strongProcess = nullptr;
680         // Callback loop
681         while (keepRunning) {
682             strongStream = weakStream.lock();
683             strongProcess = weakProcess.lock();
684             // Check if FastAudioStream or AudioProcessInClientInner is already destroyed to avoid use after free.
685             CHECK_AND_BREAK_LOG(strongStream != nullptr, "FastAudioStream destroyed, exit AudioPlayCb");
686             CHECK_AND_BREAK_LOG(strongProcess != nullptr, "AudioProcessInClientInner destroyed, exit AudioPlayCb");
687             // Main operation in callback loop
688             keepRunning = strongProcess->RecordProcessCallbackFuc(curReadPos, wakeUpTime, clientReadCost);
689         }
690         if (strongProcess != nullptr) {
691             AUDIO_INFO_LOG("Callback loop of session %{public}u end", strongProcess->sessionId_);
692         }
693     });
694     pthread_setname_np(callbackLoop_.native_handle(), "OS_AudioRecCb");
695 }
696 
Init(const AudioProcessConfig & config,std::weak_ptr<FastAudioStream> weakStream)697 bool AudioProcessInClientInner::Init(const AudioProcessConfig &config, std::weak_ptr<FastAudioStream> weakStream)
698 {
699     AUDIO_INFO_LOG("Call Init.");
700     processConfig_ = config;
701     if (!isVoipMmap_ && (config.streamInfo.format != g_targetStreamInfo.format ||
702         config.streamInfo.channels != g_targetStreamInfo.channels)) {
703         needConvert_ = true;
704     }
705     clientByteSizePerFrame_ = GetFormatSize(config.streamInfo);
706 
707     AUDIO_DEBUG_LOG("Using clientByteSizePerFrame_:%{public}zu", clientByteSizePerFrame_);
708     bool isBufferInited = InitAudioBuffer();
709     CHECK_AND_RETURN_RET_LOG(isBufferInited, isBufferInited, "%{public}s init audio buffer fail.", __func__);
710 
711     bool ret = handleTimeModel_.ConfigSampleRate(processConfig_.streamInfo.samplingRate);
712     CHECK_AND_RETURN_RET_LOG(ret != false, false, "Init LinearPosTimeModel failed.");
713     uint64_t handlePos = 0;
714     int64_t handleTime = 0;
715     audioBuffer_->GetHandleInfo(handlePos, handleTime);
716     handleTimeModel_.ResetFrameStamp(handlePos, handleTime);
717 
718     streamStatus_->store(StreamStatus::STREAM_IDEL);
719 
720     AudioBufferHolder bufferHolder = audioBuffer_->GetBufferHolder();
721     bool isIndependent = bufferHolder == AudioBufferHolder::AUDIO_SERVER_INDEPENDENT;
722     if (config.audioMode == AUDIO_MODE_RECORD) {
723         InitRecordThread(weakStream);
724     } else if (isIndependent) {
725         logUtilsTag_ = "ProcessPlay::" + std::to_string(sessionId_);
726         callbackLoop_ = std::thread([this] { this->ProcessCallbackFucIndependent(); });
727         pthread_setname_np(callbackLoop_.native_handle(), "OS_AudioPlayCb");
728     } else {
729         InitPlaybackThread(weakStream);
730     }
731 
732     int waitThreadStartTime = 5; // wait for thread start.
733     while (threadStatus_.load() == INVALID) {
734         AUDIO_DEBUG_LOG("%{public}s wait %{public}d ms for %{public}s started...", __func__, waitThreadStartTime,
735             config.audioMode == AUDIO_MODE_RECORD ? "RecordProcessCallbackFuc" : "ProcessCallbackFuc");
736         ClockTime::RelativeSleep(ONE_MILLISECOND_DURATION * waitThreadStartTime);
737     }
738 
739     isInited_ = true;
740     return true;
741 }
742 
SaveDataCallback(const std::shared_ptr<AudioDataCallback> & dataCallback)743 int32_t AudioProcessInClientInner::SaveDataCallback(const std::shared_ptr<AudioDataCallback> &dataCallback)
744 {
745     AUDIO_INFO_LOG("%{public}s enter.", __func__);
746     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
747 
748     CHECK_AND_RETURN_RET_LOG(dataCallback != nullptr, ERR_INVALID_PARAM,
749         "data callback is null.");
750     audioDataCallback_ = dataCallback;
751     return SUCCESS;
752 }
753 
SaveUnderrunCallback(const std::shared_ptr<ClientUnderrunCallBack> & underrunCallback)754 int32_t AudioProcessInClientInner::SaveUnderrunCallback(const std::shared_ptr<ClientUnderrunCallBack> &underrunCallback)
755 {
756     AUDIO_INFO_LOG("%{public}s enter.", __func__);
757     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
758 
759     CHECK_AND_RETURN_RET_LOG(underrunCallback != nullptr, ERR_INVALID_PARAM,
760         "underrun callback is null.");
761     underrunCallback_ = underrunCallback;
762     return SUCCESS;
763 }
764 
ReadFromProcessClient() const765 int32_t AudioProcessInClientInner::ReadFromProcessClient() const
766 {
767     CHECK_AND_RETURN_RET_LOG(audioBuffer_ != nullptr, ERR_INVALID_HANDLE,
768         "%{public}s audio buffer is null.", __func__);
769     uint64_t curReadPos = audioBuffer_->GetCurReadFrame();
770     Trace trace("AudioProcessInClient::ReadProcessData-<" + std::to_string(curReadPos));
771     BufferDesc readbufDesc = {nullptr, 0, 0};
772     int32_t ret = audioBuffer_->GetReadbuffer(curReadPos, readbufDesc);
773     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && readbufDesc.buffer != nullptr &&
774         readbufDesc.bufLength == spanSizeInByte_ && readbufDesc.dataLength == spanSizeInByte_,
775         ERR_OPERATION_FAILED, "get client mmap read buffer failed, ret %{public}d.", ret);
776     ret = memcpy_s(static_cast<void *>(callbackBuffer_.get()), spanSizeInByte_,
777         static_cast<void *>(readbufDesc.buffer), spanSizeInByte_);
778     CHECK_AND_RETURN_RET_LOG(ret == EOK, ERR_OPERATION_FAILED, "%{public}s memcpy fail, ret %{public}d,"
779         " spanSizeInByte %{public}zu.", __func__, ret, spanSizeInByte_);
780     DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(readbufDesc.buffer), spanSizeInByte_);
781     VolumeTools::DfxOperation(readbufDesc, processConfig_.streamInfo, logUtilsTag_, volumeDataCount_);
782 
783     ret = memset_s(readbufDesc.buffer, readbufDesc.bufLength, 0, readbufDesc.bufLength);
784     if (ret != EOK) {
785         AUDIO_WARNING_LOG("reset buffer fail, ret %{public}d.", ret);
786     }
787     return SUCCESS;
788 }
789 
790 // the buffer will be used by client
GetBufferDesc(BufferDesc & bufDesc) const791 int32_t AudioProcessInClientInner::GetBufferDesc(BufferDesc &bufDesc) const
792 {
793     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "%{public}s not inited!", __func__);
794     Trace trace("AudioProcessInClient::GetBufferDesc");
795 
796     if (processConfig_.audioMode == AUDIO_MODE_RECORD) {
797         ReadFromProcessClient();
798     }
799 
800     bufDesc.buffer = callbackBuffer_.get();
801     bufDesc.dataLength = clientSpanSizeInByte_;
802     bufDesc.bufLength = clientSpanSizeInByte_;
803     return SUCCESS;
804 }
805 
CheckIfSupport(const AudioProcessConfig & config)806 bool AudioProcessInClient::CheckIfSupport(const AudioProcessConfig &config)
807 {
808     if (config.rendererInfo.streamUsage == STREAM_USAGE_VOICE_COMMUNICATION ||
809         config.capturerInfo.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION) {
810         return true;
811     }
812 
813     if (config.streamInfo.samplingRate != SAMPLE_RATE_48000) {
814         return false;
815     }
816 
817     if (config.streamInfo.encoding != ENCODING_PCM) {
818         return false;
819     }
820 
821     if (config.streamInfo.format != SAMPLE_S16LE && config.streamInfo.format != SAMPLE_S32LE &&
822         config.streamInfo.format != SAMPLE_F32LE) {
823         return false;
824     }
825 
826     if (config.streamInfo.channels != MONO && config.streamInfo.channels != STEREO) {
827         return false;
828     }
829     return true;
830 }
831 
S16MonoToS16Stereo(const BufferDesc & srcDesc,const BufferDesc & dstDesc)832 inline bool S16MonoToS16Stereo(const BufferDesc &srcDesc, const BufferDesc &dstDesc)
833 {
834     size_t half = 2;
835     if (srcDesc.bufLength != dstDesc.bufLength / half || srcDesc.buffer == nullptr || dstDesc.buffer == nullptr) {
836         return false;
837     }
838     int16_t *stcPtr = reinterpret_cast<int16_t *>(srcDesc.buffer);
839     int16_t *dstPtr = reinterpret_cast<int16_t *>(dstDesc.buffer);
840     size_t count = srcDesc.bufLength / half;
841     for (size_t idx = 0; idx < count; idx++) {
842         *(dstPtr++) = *stcPtr;
843         *(dstPtr++) = *stcPtr++;
844     }
845     return true;
846 }
847 
S32MonoToS16Stereo(const BufferDesc & srcDesc,const BufferDesc & dstDesc)848 inline bool S32MonoToS16Stereo(const BufferDesc &srcDesc, const BufferDesc &dstDesc)
849 {
850     size_t quarter = 4;
851     if (srcDesc.bufLength != dstDesc.bufLength || srcDesc.buffer == nullptr || dstDesc.buffer == nullptr ||
852         srcDesc.bufLength % quarter != 0) {
853         return false;
854     }
855     int32_t *stcPtr = reinterpret_cast<int32_t *>(srcDesc.buffer);
856     int16_t *dstPtr = reinterpret_cast<int16_t *>(dstDesc.buffer);
857     size_t count = srcDesc.bufLength / quarter;
858 
859     double maxInt32 = INT32_MAX;
860     double maxInt16 = INT16_MAX;
861     for (size_t idx = 0; idx < count; idx++) {
862         int16_t temp = static_cast<int16_t>((static_cast<double>(*stcPtr) / maxInt32) * maxInt16);
863         stcPtr++;
864         *(dstPtr++) = temp;
865         *(dstPtr++) = temp;
866     }
867     return true;
868 }
869 
S32StereoS16Stereo(const BufferDesc & srcDesc,const BufferDesc & dstDesc)870 inline bool S32StereoS16Stereo(const BufferDesc &srcDesc, const BufferDesc &dstDesc)
871 {
872     size_t half = 2;
873     if (srcDesc.bufLength / half != dstDesc.bufLength || srcDesc.buffer == nullptr || dstDesc.buffer == nullptr ||
874         dstDesc.bufLength % half != 0) {
875         return false;
876     }
877     int32_t *stcPtr = reinterpret_cast<int32_t *>(srcDesc.buffer);
878     int16_t *dstPtr = reinterpret_cast<int16_t *>(dstDesc.buffer);
879     size_t count = srcDesc.bufLength / half / half;
880     double maxInt32 = INT32_MAX;
881     double maxInt16 = INT16_MAX;
882     for (size_t idx = 0; idx < count; idx++) {
883         int16_t temp = static_cast<int16_t>((static_cast<double>(*stcPtr) / maxInt32) * maxInt16);
884         stcPtr++;
885         *(dstPtr++) = temp;
886     }
887     return true;
888 }
889 
890 // only support MONO to STEREO and SAMPLE_S32LE to SAMPLE_S16LE
ChannelFormatConvert(const AudioStreamData & srcData,const AudioStreamData & dstData)891 bool AudioProcessInClientInner::ChannelFormatConvert(const AudioStreamData &srcData, const AudioStreamData &dstData)
892 {
893     if (srcData.streamInfo.samplingRate != dstData.streamInfo.samplingRate ||
894         srcData.streamInfo.encoding != dstData.streamInfo.encoding) {
895         return false;
896     }
897     if (srcData.streamInfo.format == SAMPLE_S16LE && srcData.streamInfo.channels == STEREO) {
898         return true; // no need convert
899     }
900     if (srcData.streamInfo.format == SAMPLE_S16LE && srcData.streamInfo.channels == MONO) {
901         return S16MonoToS16Stereo(srcData.bufferDesc, dstData.bufferDesc);
902     }
903     if (srcData.streamInfo.format == SAMPLE_S32LE && srcData.streamInfo.channels == MONO) {
904         return S32MonoToS16Stereo(srcData.bufferDesc, dstData.bufferDesc);
905     }
906     if (srcData.streamInfo.format == SAMPLE_S32LE && srcData.streamInfo.channels == STEREO) {
907         return S32StereoS16Stereo(srcData.bufferDesc, dstData.bufferDesc);
908     }
909     if (srcData.streamInfo.format == SAMPLE_F32LE && srcData.streamInfo.channels == MONO) {
910         return FormatConverter::F32MonoToS16Stereo(srcData.bufferDesc, dstData.bufferDesc);
911     }
912     if (srcData.streamInfo.format == SAMPLE_F32LE && srcData.streamInfo.channels == STEREO) {
913         return FormatConverter::F32StereoToS16Stereo(srcData.bufferDesc, dstData.bufferDesc);
914     }
915 
916     return false;
917 }
918 
CopyWithVolume(const BufferDesc & srcDesc,const BufferDesc & dstDesc) const919 void AudioProcessInClientInner::CopyWithVolume(const BufferDesc &srcDesc, const BufferDesc &dstDesc) const
920 {
921     size_t len = dstDesc.dataLength;
922     len /= 2; // SAMPLE_S16LE--> 2 byte
923     int16_t *dstPtr = reinterpret_cast<int16_t *>(dstDesc.buffer);
924     for (size_t pos = 0; len > 0; len--) {
925         int32_t sum = 0;
926         int16_t *srcPtr = reinterpret_cast<int16_t *>(srcDesc.buffer) + pos;
927         sum += (*srcPtr * static_cast<int64_t>(processVolume_ * duckVolumeInFloat_ *
928             muteVolumeInFloat_)) >> VOLUME_SHIFT_NUMBER; // 1/65536
929         pos++;
930         *dstPtr++ = sum > INT16_MAX ? INT16_MAX : (sum < INT16_MIN ? INT16_MIN : sum);
931     }
932 }
933 
ProcessVolume(const AudioStreamData & targetData) const934 void AudioProcessInClientInner::ProcessVolume(const AudioStreamData &targetData) const
935 {
936     size_t half = 2;
937     size_t len = targetData.bufferDesc.dataLength;
938     len /= half;
939     int16_t *dstPtr = reinterpret_cast<int16_t *>(targetData.bufferDesc.buffer);
940     for (; len > 0; len--) {
941         int32_t sum = 0;
942         sum += (*dstPtr * static_cast<int64_t>(processVolume_ * duckVolumeInFloat_ *
943             muteVolumeInFloat_)) >> VOLUME_SHIFT_NUMBER;
944         *dstPtr++ = sum > INT16_MAX ? INT16_MAX : (sum < INT16_MIN ? INT16_MIN : sum);
945     }
946 }
947 
ProcessData(const BufferDesc & srcDesc,const BufferDesc & dstDesc) const948 int32_t AudioProcessInClientInner::ProcessData(const BufferDesc &srcDesc, const BufferDesc &dstDesc) const
949 {
950     int32_t ret = 0;
951     size_t round = (spanSizeInFrame_ == 0 ? 1 : clientSpanSizeInFrame_ / spanSizeInFrame_);
952     size_t offSet = clientSpanSizeInByte_ / round;
953     if (!needConvert_) {
954         AudioBufferHolder bufferHolder = audioBuffer_->GetBufferHolder();
955         if (bufferHolder == AudioBufferHolder::AUDIO_SERVER_INDEPENDENT) {
956             CopyWithVolume(srcDesc, dstDesc);
957         } else {
958             ret = memcpy_s(static_cast<void *>(dstDesc.buffer), spanSizeInByte_,
959                 static_cast<void *>(srcDesc.buffer), offSet);
960             CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "Copy data failed!");
961         }
962     } else {
963         Trace traceConvert("APIC::FormatConvert");
964         AudioStreamData srcData = {processConfig_.streamInfo, srcDesc, 0, 0};
965         AudioStreamData dstData = {g_targetStreamInfo, dstDesc, 0, 0};
966         bool succ = ChannelFormatConvert(srcData, dstData);
967         CHECK_AND_RETURN_RET_LOG(succ, ERR_OPERATION_FAILED, "Convert data failed!");
968         AudioBufferHolder bufferHolder = audioBuffer_->GetBufferHolder();
969         if (bufferHolder == AudioBufferHolder::AUDIO_SERVER_INDEPENDENT) {
970             ProcessVolume(dstData);
971         }
972     }
973     return SUCCESS;
974 }
975 
Enqueue(const BufferDesc & bufDesc) const976 int32_t AudioProcessInClientInner::Enqueue(const BufferDesc &bufDesc) const
977 {
978     Trace trace("AudioProcessInClient::Enqueue");
979     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
980 
981     CHECK_AND_RETURN_RET_LOG(bufDesc.buffer != nullptr && bufDesc.bufLength == clientSpanSizeInByte_ &&
982         bufDesc.dataLength == clientSpanSizeInByte_, ERR_INVALID_PARAM,
983         "bufDesc error, bufLen %{public}zu, dataLen %{public}zu, spanSize %{public}zu.",
984         bufDesc.bufLength, bufDesc.dataLength, clientSpanSizeInByte_);
985     // check if this buffer is form us.
986     if (bufDesc.buffer != callbackBuffer_.get()) {
987         AUDIO_WARNING_LOG("the buffer is not created by client.");
988     }
989 
990     size_t round = (spanSizeInFrame_ == 0 ? 1 : clientSpanSizeInFrame_ / spanSizeInFrame_);
991     uint64_t curWritePos = audioBuffer_->GetCurWriteFrame();
992     for (size_t count = 0 ; count < round ; count++) {
993         BufferDesc curCallbackBuffer = {nullptr, 0, 0};
994         size_t offSet = clientSpanSizeInByte_ / round;
995         curCallbackBuffer.buffer = bufDesc.buffer + count * offSet;
996         curCallbackBuffer.bufLength = offSet;
997         curCallbackBuffer.dataLength = offSet;
998         uint64_t curPos = curWritePos + count * spanSizeInFrame_;
999         if (processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
1000             BufferDesc curWriteBuffer = {nullptr, 0, 0};
1001             Trace writeProcessDataTrace("AudioProcessInClient::WriteProcessData->" + std::to_string(curPos));
1002             int32_t ret = audioBuffer_->GetWriteBuffer(curPos, curWriteBuffer);
1003             CHECK_AND_RETURN_RET_LOG(ret == SUCCESS && curWriteBuffer.buffer != nullptr &&
1004                 curWriteBuffer.bufLength == spanSizeInByte_ && curWriteBuffer.dataLength == spanSizeInByte_,
1005                 ERR_OPERATION_FAILED, "get write buffer fail, ret:%{public}d", ret);
1006             ret = ProcessData(curCallbackBuffer, curWriteBuffer);
1007             if (ret != SUCCESS) {
1008                 return ERR_OPERATION_FAILED;
1009             }
1010             writeProcessDataTrace.End();
1011 
1012             DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(curCallbackBuffer.buffer), offSet);
1013             VolumeTools::DfxOperation(curCallbackBuffer, processConfig_.streamInfo, logUtilsTag_, volumeDataCount_);
1014         }
1015     }
1016 
1017     if (memset_s(callbackBuffer_.get(), clientSpanSizeInByte_, 0, clientSpanSizeInByte_) != EOK) {
1018         AUDIO_WARNING_LOG("reset callback buffer fail.");
1019     }
1020 
1021     return SUCCESS;
1022 }
1023 
SetVolume(int32_t vol)1024 int32_t AudioProcessInClientInner::SetVolume(int32_t vol)
1025 {
1026     AUDIO_INFO_LOG("proc client mode %{public}d to %{public}d.", processConfig_.audioMode, vol);
1027     Trace trace("AudioProcessInClient::SetVolume " + std::to_string(vol));
1028     CHECK_AND_RETURN_RET_LOG(vol >= 0 && vol <= PROCESS_VOLUME_MAX, ERR_INVALID_PARAM,
1029         "SetVolume failed, invalid volume:%{public}d", vol);
1030     processVolume_ = vol;
1031     return SUCCESS;
1032 }
1033 
Start()1034 int32_t AudioProcessInClientInner::Start()
1035 {
1036     Trace traceStart("AudioProcessInClient::Start");
1037     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
1038 
1039     const auto [samplingRate, encoding, format, channels, channelLayout] = processConfig_.streamInfo;
1040     // eg: 100005_dump_process_client_audio_48000_2_1.pcm
1041     std::string dumpFileName = std::to_string(sessionId_) + "_dump_process_client_audio_" +
1042         std::to_string(samplingRate) + '_' + std::to_string(channels) + '_' + std::to_string(format) +
1043         ".pcm";
1044     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_CLIENT_PARA, dumpFileName, &dumpFile_);
1045 
1046     std::lock_guard<std::mutex> lock(statusSwitchLock_);
1047     if (streamStatus_->load() == StreamStatus::STREAM_RUNNING) {
1048         AUDIO_INFO_LOG("Start find already started");
1049         return SUCCESS;
1050     }
1051 
1052     startFadein_.store(true);
1053     StreamStatus targetStatus = StreamStatus::STREAM_IDEL;
1054     bool ret = streamStatus_->compare_exchange_strong(targetStatus, StreamStatus::STREAM_STARTING);
1055     if (!ret) {
1056         startFadein_.store(false);
1057     }
1058     CHECK_AND_RETURN_RET_LOG(
1059         ret, ERR_ILLEGAL_STATE, "Start failed, invalid status: %{public}s", GetStatusInfo(targetStatus).c_str());
1060 
1061     if (processProxy_->Start() != SUCCESS) {
1062         streamStatus_->store(StreamStatus::STREAM_IDEL);
1063         AUDIO_ERR_LOG("Start failed to call process proxy, reset status to IDEL.");
1064         startFadein_.store(false);
1065         threadStatusCV_.notify_all();
1066         return ERR_OPERATION_FAILED;
1067     }
1068     UpdateHandleInfo();
1069     streamStatus_->store(StreamStatus::STREAM_RUNNING);
1070     threadStatusCV_.notify_all();
1071     return SUCCESS;
1072 }
1073 
Pause(bool isFlush)1074 int32_t AudioProcessInClientInner::Pause(bool isFlush)
1075 {
1076     Trace tracePause("AudioProcessInClient::Pause");
1077     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
1078 
1079     std::lock_guard<std::mutex> lock(statusSwitchLock_);
1080     if (streamStatus_->load() == StreamStatus::STREAM_PAUSED) {
1081         AUDIO_INFO_LOG("Pause find already paused");
1082         return SUCCESS;
1083     }
1084     startFadeout_.store(true);
1085     StreamStatus targetStatus = StreamStatus::STREAM_RUNNING;
1086     bool ret = streamStatus_->compare_exchange_strong(targetStatus, StreamStatus::STREAM_PAUSING);
1087     if (!ret) {
1088         startFadeout_.store(false);
1089     }
1090     CHECK_AND_RETURN_RET_LOG(
1091         ret, ERR_ILLEGAL_STATE, "Pause failed, invalid status : %{public}s", GetStatusInfo(targetStatus).c_str());
1092     ClockTime::RelativeSleep(MAX_STOP_FADING_DURATION_NANO);
1093     if (processProxy_->Pause(isFlush) != SUCCESS) {
1094         streamStatus_->store(StreamStatus::STREAM_RUNNING);
1095         AUDIO_ERR_LOG("Pause failed to call process proxy, reset status to RUNNING");
1096         startFadeout_.store(false);
1097         threadStatusCV_.notify_all(); // avoid thread blocking with status PAUSING
1098         return ERR_OPERATION_FAILED;
1099     }
1100     startFadeout_.store(false);
1101     streamStatus_->store(StreamStatus::STREAM_PAUSED);
1102 
1103     lastPausedTime_ = ClockTime::GetCurNano();
1104 
1105     return SUCCESS;
1106 }
1107 
Resume()1108 int32_t AudioProcessInClientInner::Resume()
1109 {
1110     Trace traceResume("AudioProcessInClient::Resume");
1111     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
1112     std::lock_guard<std::mutex> lock(statusSwitchLock_);
1113 
1114     if (streamStatus_->load() == StreamStatus::STREAM_RUNNING) {
1115         AUDIO_INFO_LOG("Resume find already running");
1116         return SUCCESS;
1117     }
1118 
1119     startFadein_.store(true);
1120 
1121     StreamStatus pausedStatus = StreamStatus::STREAM_PAUSED;
1122     StreamStatus stoppedStatus = StreamStatus::STREAM_STOPPED;
1123     if (!streamStatus_->compare_exchange_strong(pausedStatus, StreamStatus::STREAM_STARTING) &&
1124         !streamStatus_->compare_exchange_strong(stoppedStatus, StreamStatus::STREAM_STARTING)) {
1125         startFadein_.store(false);
1126         AUDIO_ERR_LOG("Resume failed, invalid status : %{public}s", GetStatusInfo(stoppedStatus).c_str());
1127         return ERR_ILLEGAL_STATE;
1128     }
1129 
1130     if (processProxy_->Resume() != SUCCESS) {
1131         streamStatus_->store(StreamStatus::STREAM_PAUSED);
1132         AUDIO_ERR_LOG("Resume failed to call process proxy, reset status to PAUSED.");
1133         startFadein_.store(false);
1134         threadStatusCV_.notify_all();
1135         return ERR_OPERATION_FAILED;
1136     }
1137 
1138     if (ClockTime::GetCurNano() - lastPausedTime_ > DELAY_RESYNC_TIME) {
1139         UpdateHandleInfo(false, true);
1140         lastPausedTime_ = INT64_MAX;
1141     } else {
1142         UpdateHandleInfo();
1143     }
1144 
1145     streamStatus_->store(StreamStatus::STREAM_RUNNING);
1146     threadStatusCV_.notify_all();
1147 
1148     return SUCCESS;
1149 }
1150 
Stop()1151 int32_t AudioProcessInClientInner::Stop()
1152 {
1153     Trace traceStop("AudioProcessInClient::Stop");
1154     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
1155     std::lock_guard<std::mutex> lock(statusSwitchLock_);
1156     if (streamStatus_->load() == StreamStatus::STREAM_STOPPED) {
1157         AUDIO_INFO_LOG("Stop find already stopped");
1158         return SUCCESS;
1159     }
1160 
1161     StreamStatus oldStatus = streamStatus_->load();
1162     CHECK_AND_RETURN_RET_LOG(oldStatus != STREAM_IDEL && oldStatus != STREAM_RELEASED && oldStatus != STREAM_INVALID,
1163         ERR_ILLEGAL_STATE, "Stop failed, invalid status : %{public}s", GetStatusInfo(oldStatus).c_str());
1164     if (oldStatus == STREAM_STARTING || oldStatus == STREAM_RUNNING) {
1165         startFadeout_.store(true);
1166     }
1167     streamStatus_->store(StreamStatus::STREAM_STOPPING);
1168 
1169     ClockTime::RelativeSleep(MAX_STOP_FADING_DURATION_NANO);
1170 
1171     processProxy_->SetUnderrunCount(underflowCount_);
1172     if (processProxy_->Stop() != SUCCESS) {
1173         streamStatus_->store(oldStatus);
1174         AUDIO_ERR_LOG("Stop failed in server, reset status to %{public}s", GetStatusInfo(oldStatus).c_str());
1175         startFadeout_.store(false);
1176         threadStatusCV_.notify_all(); // avoid thread blocking with status RUNNING
1177         return ERR_OPERATION_FAILED;
1178     }
1179     startFadeout_.store(false);
1180     streamStatus_->store(StreamStatus::STREAM_STOPPED);
1181     AUDIO_INFO_LOG("Success stop proc client mode %{public}d form %{public}s.",
1182         processConfig_.audioMode, GetStatusInfo(oldStatus).c_str());
1183     return SUCCESS;
1184 }
1185 
Release(bool isSwitchStream)1186 int32_t AudioProcessInClientInner::Release(bool isSwitchStream)
1187 {
1188     Trace traceRelease("AudioProcessInClient::Release");
1189     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
1190     AUDIO_INFO_LOG("AudioProcessInClientInner::Release()");
1191     // not lock as status is already released
1192     if (streamStatus_->load() == StreamStatus::STREAM_RELEASED) {
1193         AUDIO_INFO_LOG("Stream status is already released");
1194         return SUCCESS;
1195     }
1196     Stop();
1197     isCallbackLoopEnd_ = true;
1198     threadStatusCV_.notify_all();
1199     std::lock_guard<std::mutex> lock(statusSwitchLock_);
1200     StreamStatus currentStatus = streamStatus_->load();
1201     if (currentStatus != STREAM_STOPPED) {
1202         AUDIO_WARNING_LOG("Release in currentStatus:%{public}s", GetStatusInfo(currentStatus).c_str());
1203     }
1204 
1205     if (processProxy_->Release(isSwitchStream) != SUCCESS) {
1206         AUDIO_ERR_LOG("Release may failed in server");
1207         threadStatusCV_.notify_all(); // avoid thread blocking with status RUNNING
1208         return ERR_OPERATION_FAILED;
1209     }
1210 
1211     streamStatus_->store(StreamStatus::STREAM_RELEASED);
1212     AUDIO_INFO_LOG("Success release proc client mode %{public}d.", processConfig_.audioMode);
1213     isInited_ = false;
1214     return SUCCESS;
1215 }
1216 
1217 // client should call GetBufferDesc and Enqueue in OnHandleData
CallClientHandleCurrent()1218 void AudioProcessInClientInner::CallClientHandleCurrent()
1219 {
1220     Trace trace("AudioProcessInClient::CallClientHandleCurrent");
1221     std::shared_ptr<AudioDataCallback> cb = audioDataCallback_.lock();
1222     CHECK_AND_RETURN_LOG(cb != nullptr, "audio data callback is null.");
1223 
1224     int64_t stamp = ClockTime::GetCurNano();
1225     cb->OnHandleData(clientSpanSizeInByte_);
1226     stamp = ClockTime::GetCurNano() - stamp;
1227     if (stamp > MAX_WRITE_COST_DURATION_NANO) {
1228         if (processConfig_.audioMode == AUDIO_MODE_PLAYBACK) {
1229             underflowCount_++;
1230         } else {
1231             overflowCount_++;
1232         }
1233         // todo
1234         // handle write time out: send underrun msg to client, reset time model with latest server handle time.
1235     }
1236 
1237     int64_t limit = isVoipMmap_ ? VOIP_MILLISECOND_DURATION : MAX_WRITE_COST_DURATION_NANO;
1238     if (stamp + ONE_MILLISECOND_DURATION > limit) {
1239         AUDIO_WARNING_LOG("Client handle cb too slow, cost %{public}" PRId64"us", stamp / AUDIO_MS_PER_SECOND);
1240     }
1241 }
1242 
UpdateHandleInfo(bool isAysnc,bool resetReadWritePos)1243 void AudioProcessInClientInner::UpdateHandleInfo(bool isAysnc, bool resetReadWritePos)
1244 {
1245     Trace traceSync("AudioProcessInClient::UpdateHandleInfo");
1246     uint64_t serverHandlePos = 0;
1247     int64_t serverHandleTime = 0;
1248     int32_t ret = processProxy_->RequestHandleInfo(isAysnc);
1249     CHECK_AND_RETURN_LOG(ret == SUCCESS, "RequestHandleInfo failed ret:%{public}d", ret);
1250     audioBuffer_->GetHandleInfo(serverHandlePos, serverHandleTime);
1251 
1252     CheckPosTimeRes res = handleTimeModel_.UpdataFrameStamp(serverHandlePos, serverHandleTime);
1253     if (res == CHECK_FAILED) {
1254         handleTimeModel_.ResetFrameStamp(serverHandlePos, serverHandleTime);
1255     }
1256 
1257     if (resetReadWritePos) {
1258         uint64_t nextWritePos = serverHandlePos + spanSizeInFrame_;
1259         ResetAudioBuffer();
1260         ret = audioBuffer_->ResetCurReadWritePos(nextWritePos, nextWritePos);
1261         CHECK_AND_RETURN_LOG(ret == SUCCESS, "ResetCurReadWritePos failed ret:%{public}d", ret);
1262     }
1263 }
1264 
ResetAudioBuffer()1265 void AudioProcessInClientInner::ResetAudioBuffer()
1266 {
1267     CHECK_AND_RETURN_LOG((audioBuffer_ != nullptr), "%{public}s: audio buffer is null.", __func__);
1268 
1269     uint32_t spanCount = audioBuffer_->GetSpanCount();
1270     for (uint32_t i = 0; i < spanCount; i++) {
1271         SpanInfo *spanInfo = audioBuffer_->GetSpanInfoByIndex(i);
1272         if (spanInfo == nullptr) {
1273             AUDIO_ERR_LOG("ResetAudiobuffer failed.");
1274             return;
1275         }
1276         spanInfo->spanStatus = SPAN_READ_DONE;
1277         spanInfo->offsetInFrame = 0;
1278 
1279         spanInfo->readStartTime = 0;
1280         spanInfo->readDoneTime = 0;
1281 
1282         spanInfo->writeStartTime = 0;
1283         spanInfo->writeDoneTime = 0;
1284 
1285         spanInfo->volumeStart = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
1286         spanInfo->volumeEnd = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
1287         spanInfo->isMute = false;
1288     }
1289     return;
1290 }
1291 
GetPredictNextHandleTime(uint64_t posInFrame,bool isIndependent)1292 int64_t AudioProcessInClientInner::GetPredictNextHandleTime(uint64_t posInFrame, bool isIndependent)
1293 {
1294     Trace trace("AudioProcessInClient::GetPredictNextRead");
1295     CHECK_AND_RETURN_RET_LOG(spanSizeInFrame_ != 0, 0, "spanSizeInFrame is 0.");
1296     uint64_t handleSpanCnt = 0;
1297     if (spanSizeInFrame_ != 0) {
1298         handleSpanCnt = posInFrame / spanSizeInFrame_;
1299     }
1300     uint32_t startPeriodCnt = 20; // sync each time when start
1301     uint32_t oneBigPeriodCnt = 40; // 200ms
1302     if (isIndependent) {
1303         if (handleSpanCnt % oneBigPeriodCnt == 0) {
1304             UpdateHandleInfo(true);
1305         }
1306     } else {
1307         if (handleSpanCnt < startPeriodCnt || handleSpanCnt % oneBigPeriodCnt == 0) {
1308             UpdateHandleInfo();
1309         }
1310     }
1311 
1312     int64_t nextHandleTime = handleTimeModel_.GetTimeOfPos(posInFrame);
1313 
1314     return nextHandleTime;
1315 }
1316 
PrepareNext(uint64_t curHandPos,int64_t & wakeUpTime)1317 bool AudioProcessInClientInner::PrepareNext(uint64_t curHandPos, int64_t &wakeUpTime)
1318 {
1319     Trace trace("AudioProcessInClient::PrepareNext " + std::to_string(curHandPos));
1320     int64_t handleModifyTime = 0;
1321     if (processConfig_.audioMode == AUDIO_MODE_RECORD) {
1322         handleModifyTime = RECORD_HANDLE_DELAY_NANO;
1323     } else {
1324         handleModifyTime = -WRITE_BEFORE_DURATION_NANO;
1325     }
1326 
1327     int64_t nextServerHandleTime = GetPredictNextHandleTime(curHandPos) + handleModifyTime;
1328     if (nextServerHandleTime < ClockTime::GetCurNano()) {
1329         wakeUpTime = ClockTime::GetCurNano() + ONE_MILLISECOND_DURATION; // make sure less than duration
1330     } else {
1331         wakeUpTime = nextServerHandleTime;
1332     }
1333     AUDIO_DEBUG_LOG("%{public}s end, audioMode %{public}d, curReadPos %{public}" PRIu64", nextServerHandleTime "
1334         "%{public}" PRId64" wakeUpTime %{public}" PRId64".", __func__, processConfig_.audioMode, curHandPos,
1335         nextServerHandleTime, wakeUpTime);
1336     return true;
1337 }
1338 
ClientPrepareNextLoop(uint64_t curWritePos,int64_t & wakeUpTime)1339 bool AudioProcessInClientInner::ClientPrepareNextLoop(uint64_t curWritePos, int64_t &wakeUpTime)
1340 {
1341     size_t round = (spanSizeInFrame_ == 0 ? 1 : clientSpanSizeInFrame_ / spanSizeInFrame_);
1342     for (size_t count = 0; count < round; count++) {
1343         bool ret = PrepareNext(curWritePos + count * spanSizeInFrame_, wakeUpTime);
1344         CHECK_AND_RETURN_RET_LOG(ret, false, "PrepareNextLoop in process failed!");
1345     }
1346     return true;
1347 }
1348 
CallExitStandBy()1349 void AudioProcessInClientInner::CallExitStandBy()
1350 {
1351     Trace trace("AudioProcessInClient::CallExitStandBy::" + std::to_string(sessionId_));
1352     int32_t result = processProxy_->Start();
1353     StreamStatus targetStatus = StreamStatus::STREAM_STARTING;
1354     bool ret = streamStatus_->compare_exchange_strong(targetStatus, StreamStatus::STREAM_RUNNING);
1355     AUDIO_INFO_LOG("Call start result:%{public}d  status change: %{public}s", result, ret ? "success" : "fail");
1356     UpdateHandleInfo();
1357 }
1358 
GetStatusInfo(StreamStatus status)1359 std::string AudioProcessInClientInner::GetStatusInfo(StreamStatus status)
1360 {
1361     switch (status) {
1362         case STREAM_IDEL:
1363             return "STREAM_IDEL";
1364         case STREAM_STARTING:
1365             return "STREAM_STARTING";
1366         case STREAM_RUNNING:
1367             return "STREAM_RUNNING";
1368         case STREAM_PAUSING:
1369             return "STREAM_PAUSING";
1370         case STREAM_PAUSED:
1371             return "STREAM_PAUSED";
1372         case STREAM_STOPPING:
1373             return "STREAM_STOPPING";
1374         case STREAM_STOPPED:
1375             return "STREAM_STOPPED";
1376         case STREAM_RELEASED:
1377             return "STREAM_RELEASED";
1378         case STREAM_INVALID:
1379             return "STREAM_INVALID";
1380         default:
1381             break;
1382     }
1383     return "NO_SUCH_STATUS";
1384 }
1385 
KeepLoopRunning()1386 bool AudioProcessInClientInner::KeepLoopRunning()
1387 {
1388     StreamStatus targetStatus = STREAM_INVALID;
1389 
1390     switch (streamStatus_->load()) {
1391         case STREAM_RUNNING:
1392             return true;
1393         case STREAM_STAND_BY:
1394             AUDIO_INFO_LOG("Status is STAND_BY, let's call exit!");
1395             CallExitStandBy();
1396             return true;
1397         case STREAM_STARTING:
1398             targetStatus = STREAM_RUNNING;
1399             break;
1400         case STREAM_IDEL:
1401             targetStatus = STREAM_STARTING;
1402             break;
1403         case STREAM_PAUSING:
1404             targetStatus = STREAM_PAUSED;
1405             break;
1406         case STREAM_PAUSED:
1407             targetStatus = STREAM_STARTING;
1408             break;
1409         case STREAM_STOPPING:
1410             targetStatus = STREAM_STOPPED;
1411             break;
1412         case STREAM_STOPPED:
1413             targetStatus = STREAM_RELEASED;
1414             break;
1415         default:
1416             break;
1417     }
1418 
1419     if (startFadeout_.load() &&
1420         (targetStatus == STREAM_PAUSED || targetStatus == STREAM_STOPPED || targetStatus == STREAM_RELEASED)) {
1421         // do one more time to prepare fade out span buffer
1422         return true;
1423     }
1424 
1425     Trace trace("AudioProcessInClient::InWaitStatus");
1426     std::unique_lock<std::mutex> lock(loopThreadLock_);
1427     AUDIO_DEBUG_LOG("Process status is %{public}s now, wait for %{public}s...",
1428         GetStatusInfo(streamStatus_->load()).c_str(), GetStatusInfo(targetStatus).c_str());
1429     threadStatus_ = WAITTING;
1430     threadStatusCV_.wait(lock);
1431     AUDIO_DEBUG_LOG("Process wait end. Cur is %{public}s now, target is %{public}s...",
1432         GetStatusInfo(streamStatus_->load()).c_str(), GetStatusInfo(targetStatus).c_str());
1433 
1434     return false;
1435 }
1436 
RecordProcessCallbackFuc(uint64_t & curReadPos,int64_t & wakeUpTime,int64_t clientReadCost)1437 bool AudioProcessInClientInner::RecordProcessCallbackFuc(uint64_t &curReadPos, int64_t &wakeUpTime,
1438     int64_t clientReadCost)
1439 {
1440     if (isCallbackLoopEnd_ || audioBuffer_ == nullptr) {
1441         return false;
1442     }
1443     if (!KeepLoopRunning()) {
1444         return true;
1445     }
1446     threadStatus_ = INRUNNING;
1447     Trace traceLoop("AudioProcessInClient Record InRunning");
1448     if (needReSyncPosition_ && RecordReSyncServicePos() == SUCCESS) {
1449         wakeUpTime = ClockTime::GetCurNano();
1450         needReSyncPosition_ = false;
1451         return true;
1452     }
1453     int64_t curTime = ClockTime::GetCurNano();
1454     int64_t wakeupCost = curTime - wakeUpTime;
1455     if (wakeupCost > ONE_MILLISECOND_DURATION) {
1456         AUDIO_WARNING_LOG("loop wake up too late, cost %{public}" PRId64"us", wakeupCost / AUDIO_MS_PER_SECOND);
1457         wakeUpTime = curTime;
1458     }
1459 
1460     curReadPos = audioBuffer_->GetCurReadFrame();
1461     int32_t recordPrepare = RecordPrepareCurrent(curReadPos);
1462     CHECK_AND_RETURN_RET_LOG(recordPrepare == SUCCESS, true, "prepare current fail.");
1463     CallClientHandleCurrent();
1464     int32_t recordFinish = RecordFinishHandleCurrent(curReadPos, clientReadCost);
1465     CHECK_AND_RETURN_RET_LOG(recordFinish == SUCCESS, true, "finish handle current fail.");
1466 
1467     bool ret = PrepareNext(curReadPos, wakeUpTime);
1468     CHECK_AND_RETURN_RET_LOG(ret, false, "prepare next loop in process fail.");
1469 
1470     threadStatus_ = SLEEPING;
1471     curTime = ClockTime::GetCurNano();
1472     if (wakeUpTime > curTime && wakeUpTime - curTime < static_cast<int64_t>(spanSizeInMs_) *
1473         ONE_MILLISECOND_DURATION + clientReadCost) {
1474         ClockTime::AbsoluteSleep(wakeUpTime);
1475     } else {
1476         Trace trace("RecordBigWakeUpTime");
1477         AUDIO_WARNING_LOG("%{public}s wakeUpTime is too late...", __func__);
1478         ClockTime::RelativeSleep(spanSizeInMs_ * ONE_MILLISECOND_DURATION);
1479     }
1480     return true;
1481 }
1482 
RecordReSyncServicePos()1483 int32_t AudioProcessInClientInner::RecordReSyncServicePos()
1484 {
1485     CHECK_AND_RETURN_RET_LOG(processProxy_ != nullptr && audioBuffer_ != nullptr, ERR_INVALID_HANDLE,
1486         "%{public}s process proxy or audio buffer is null.", __func__);
1487     uint64_t serverHandlePos = 0;
1488     int64_t serverHandleTime = 0;
1489     int32_t tryTimes = 3;
1490     int32_t ret = 0;
1491     while (tryTimes > 0) {
1492         ret = processProxy_->RequestHandleInfo();
1493         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "%{public}s request handle info fail, ret %{public}d.",
1494             __func__, ret);
1495 
1496         CHECK_AND_RETURN_RET_LOG(audioBuffer_->GetHandleInfo(serverHandlePos, serverHandleTime), ERR_OPERATION_FAILED,
1497             "%{public}s get handle info fail.", __func__);
1498         if (serverHandlePos > 0) {
1499             break;
1500         }
1501         ClockTime::RelativeSleep(MAX_READ_COST_DURATION_NANO);
1502         tryTimes--;
1503     }
1504     AUDIO_INFO_LOG("%{public}s get handle info OK, tryTimes %{public}d, serverHandlePos %{public}" PRIu64", "
1505         "serverHandleTime %{public}" PRId64".", __func__, tryTimes, serverHandlePos, serverHandleTime);
1506     ClockTime::AbsoluteSleep(serverHandleTime + RECORD_HANDLE_DELAY_NANO);
1507 
1508     ret = audioBuffer_->SetCurReadFrame(serverHandlePos);
1509     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "%{public}s set curReadPos fail, ret %{public}d.", __func__, ret);
1510     return SUCCESS;
1511 }
1512 
RecordPrepareCurrent(uint64_t curReadPos)1513 int32_t AudioProcessInClientInner::RecordPrepareCurrent(uint64_t curReadPos)
1514 {
1515     CHECK_AND_RETURN_RET_LOG(audioBuffer_ != nullptr, ERR_INVALID_HANDLE,
1516         "%{public}s audio buffer is null.", __func__);
1517     SpanInfo *curReadSpan = audioBuffer_->GetSpanInfo(curReadPos);
1518     CHECK_AND_RETURN_RET_LOG(curReadSpan != nullptr, ERR_INVALID_HANDLE,
1519         "%{public}s get read span info of process client fail.", __func__);
1520 
1521     int tryCount = 10;
1522     SpanStatus targetStatus = SpanStatus::SPAN_WRITE_DONE;
1523     while (!curReadSpan->spanStatus.compare_exchange_strong(targetStatus, SpanStatus::SPAN_READING)
1524         && tryCount > 0) {
1525         AUDIO_WARNING_LOG("%{public}s unready, curReadSpan %{public}" PRIu64", curSpanStatus %{public}d, wait 2ms.",
1526             __func__, curReadPos, curReadSpan->spanStatus.load());
1527         if (curReadSpan->spanStatus.load() == SpanStatus::SPAN_READING) {
1528             AUDIO_WARNING_LOG("Change status to reading while status is already reading!");
1529             return SUCCESS;
1530         }
1531         targetStatus = SpanStatus::SPAN_WRITE_DONE;
1532         tryCount--;
1533         ClockTime::RelativeSleep(RECORD_RESYNC_SLEEP_NANO);
1534     }
1535     CHECK_AND_RETURN_RET_LOG(tryCount > 0, ERR_INVALID_READ,
1536         "%{public}s wait too long, curReadSpan %{public}" PRIu64".", __func__, curReadPos);
1537 
1538     curReadSpan->readStartTime = ClockTime::GetCurNano();
1539     return SUCCESS;
1540 }
1541 
RecordFinishHandleCurrent(uint64_t & curReadPos,int64_t & clientReadCost)1542 int32_t AudioProcessInClientInner::RecordFinishHandleCurrent(uint64_t &curReadPos, int64_t &clientReadCost)
1543 {
1544     CHECK_AND_RETURN_RET_LOG(audioBuffer_ != nullptr, ERR_INVALID_HANDLE,
1545         "%{public}s audio buffer is null.", __func__);
1546     SpanInfo *curReadSpan = audioBuffer_->GetSpanInfo(curReadPos);
1547     CHECK_AND_RETURN_RET_LOG(curReadSpan != nullptr, ERR_INVALID_HANDLE,
1548         "%{public}s get read span info of process client fail.", __func__);
1549 
1550     SpanStatus targetStatus = SpanStatus::SPAN_READING;
1551     if (!curReadSpan->spanStatus.compare_exchange_strong(targetStatus, SpanStatus::SPAN_READ_DONE)) {
1552         AUDIO_ERR_LOG("%{public}s status error, curReadSpan %{public}" PRIu64", curSpanStatus %{public}d.",
1553             __func__, curReadPos, curReadSpan->spanStatus.load());
1554         return ERR_INVALID_OPERATION;
1555     }
1556     curReadSpan->readDoneTime = ClockTime::GetCurNano();
1557 
1558     clientReadCost = curReadSpan->readDoneTime - curReadSpan->readStartTime;
1559     if (clientReadCost > MAX_READ_COST_DURATION_NANO) {
1560         AUDIO_WARNING_LOG("Client read cost too long...");
1561     }
1562 
1563     uint64_t nextWritePos = curReadPos + spanSizeInFrame_;
1564     int32_t ret = audioBuffer_->SetCurReadFrame(nextWritePos);
1565     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "%{public}s set next hand frame %{public}" PRIu64" fail, "
1566         "ret %{public}d.", __func__, nextWritePos, ret);
1567     curReadPos = nextWritePos;
1568 
1569     return SUCCESS;
1570 }
1571 
PrepareCurrent(uint64_t curWritePos)1572 bool AudioProcessInClientInner::PrepareCurrent(uint64_t curWritePos)
1573 {
1574     Trace trace("AudioProcessInClient::PrepareCurrent " + std::to_string(curWritePos));
1575     SpanInfo *tempSpan = audioBuffer_->GetSpanInfo(curWritePos);
1576     if (tempSpan == nullptr) {
1577         AUDIO_ERR_LOG("GetSpanInfo failed!");
1578         return false;
1579     }
1580 
1581     int tryCount = 50; // try 50 * 2 = 100ms
1582     SpanStatus targetStatus = SpanStatus::SPAN_READ_DONE;
1583     while (!tempSpan->spanStatus.compare_exchange_strong(targetStatus, SpanStatus::SPAN_WRITTING) && tryCount > 0) {
1584         tryCount--;
1585         AUDIO_PRERELEASE_LOGW("span %{public}" PRIu64" not ready, status: %{public}d, wait 2ms.", curWritePos,
1586             targetStatus);
1587         targetStatus = SpanStatus::SPAN_READ_DONE;
1588         ClockTime::RelativeSleep(ONE_MILLISECOND_DURATION + ONE_MILLISECOND_DURATION);
1589     }
1590     // If the last attempt is successful, tryCount will be equal to zero.
1591     CHECK_AND_RETURN_RET_LOG(tryCount >= 0, false,
1592         "wait on current span  %{public}" PRIu64" too long...", curWritePos);
1593     tempSpan->writeStartTime = ClockTime::GetCurNano();
1594     return true;
1595 }
1596 
PrepareCurrentLoop(uint64_t curWritePos)1597 bool AudioProcessInClientInner::PrepareCurrentLoop(uint64_t curWritePos)
1598 {
1599     size_t round = (spanSizeInFrame_ == 0 ? 1 : clientSpanSizeInFrame_ / spanSizeInFrame_);
1600     for (size_t count = 0; count < round; count++) {
1601         uint64_t tmp = curWritePos + count * static_cast<uint64_t>(spanSizeInFrame_);
1602         bool ret = PrepareCurrent(tmp);
1603         CHECK_AND_RETURN_RET_LOG(ret, false, "PrepareCurrent failed at %{public}" PRIu64" ", tmp);
1604     }
1605     return true;
1606 }
1607 
FinishHandleCurrent(uint64_t & curWritePos,int64_t & clientWriteCost)1608 bool AudioProcessInClientInner::FinishHandleCurrent(uint64_t &curWritePos, int64_t &clientWriteCost)
1609 {
1610     Trace trace("AudioProcessInClient::FinishHandleCurrent " + std::to_string(curWritePos));
1611     SpanInfo *tempSpan = audioBuffer_->GetSpanInfo(curWritePos);
1612     CHECK_AND_RETURN_RET_LOG(tempSpan != nullptr, false, "GetSpanInfo failed!");
1613 
1614     int32_t ret = ERROR;
1615     // mark status write-done and then server can read
1616     SpanStatus targetStatus = SpanStatus::SPAN_WRITTING;
1617     if (tempSpan->spanStatus.load() == targetStatus) {
1618         uint64_t nextWritePos = curWritePos + spanSizeInFrame_;
1619         ret = audioBuffer_->SetCurWriteFrame(nextWritePos); // move ahead before writedone
1620         curWritePos = nextWritePos;
1621         tempSpan->spanStatus.store(SpanStatus::SPAN_WRITE_DONE);
1622     }
1623     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, false,
1624         "SetCurWriteFrame %{public}" PRIu64" failed, ret:%{public}d", curWritePos, ret);
1625     tempSpan->writeDoneTime = ClockTime::GetCurNano();
1626     tempSpan->volumeStart = static_cast<int32_t>(processVolume_ * duckVolumeInFloat_ * muteVolumeInFloat_);
1627     tempSpan->volumeEnd = static_cast<int32_t>(processVolume_ * duckVolumeInFloat_ * muteVolumeInFloat_);
1628     clientWriteCost = tempSpan->writeDoneTime - tempSpan->writeStartTime;
1629 
1630     return true;
1631 }
1632 
FinishHandleCurrentLoop(uint64_t & curWritePos,int64_t & clientWriteCost)1633 bool AudioProcessInClientInner::FinishHandleCurrentLoop(uint64_t &curWritePos, int64_t &clientWriteCost)
1634 {
1635     size_t round = (spanSizeInFrame_ == 0 ? 1 : clientSpanSizeInFrame_ / spanSizeInFrame_);
1636     for (size_t count = 0; count < round; count++) {
1637         uint64_t tmp = curWritePos + count * static_cast<uint64_t>(spanSizeInFrame_);
1638         bool ret = FinishHandleCurrent(tmp, clientWriteCost);
1639         CHECK_AND_RETURN_RET_LOG(ret, false, "FinishHandleCurrent failed at %{public}" PRIu64" ", tmp);
1640     }
1641     return true;
1642 }
1643 
DoFadeInOut(uint64_t & curWritePos)1644 void AudioProcessInClientInner::DoFadeInOut(uint64_t &curWritePos)
1645 {
1646     if (startFadein_.load() || startFadeout_.load()) {
1647         BufferDesc buffDesc;
1648         CHECK_AND_RETURN_LOG(audioBuffer_ != nullptr, "audioBuffer_ is null.");
1649         audioBuffer_->GetWriteBuffer(curWritePos, buffDesc);
1650         CHECK_AND_RETURN_LOG(buffDesc.buffer != nullptr, "audioBuffer_ is null.");
1651         int16_t *dstPtr = reinterpret_cast<int16_t *>(buffDesc.buffer);
1652         uint8_t channels = processConfig_.streamInfo.channels;
1653         size_t dataLength = buffDesc.dataLength / (2 * channels); //  SAMPLE_S16LE,2 bytes per frame
1654 
1655         bool isFadeOut = startFadeout_.load();
1656         float fadeStep = 1.0f / dataLength;
1657         for (size_t i = 0; i < dataLength; i++) {
1658             float fadeFactor;
1659             if (!isFadeOut) {
1660                 fadeFactor = (i + 1) * fadeStep;
1661             } else {
1662                 fadeFactor = 1.0f - ((i + 1) * fadeStep);
1663             }
1664             for (uint8_t j = 0; j < channels; j++) {
1665                 dstPtr[i * channels + j] *= fadeFactor;
1666             }
1667         }
1668 
1669         if (isFadeOut) {
1670             startFadeout_.store(false);
1671         } else {
1672             startFadein_.store(false);
1673         }
1674     }
1675 }
1676 
ProcessCallbackFuc(uint64_t & curWritePos,int64_t & curTime,int64_t & wakeUpTime,int64_t & clientWriteCost)1677 bool AudioProcessInClientInner::ProcessCallbackFuc(uint64_t &curWritePos, int64_t &curTime,
1678     int64_t &wakeUpTime, int64_t &clientWriteCost)
1679 {
1680     if (isCallbackLoopEnd_ && !startFadeout_.load()) {
1681         return false;
1682     }
1683     if (!KeepLoopRunning()) {
1684         return true;
1685     }
1686     threadStatus_ = INRUNNING;
1687     Trace traceLoop("AudioProcessInClient::InRunning");
1688     CheckIfWakeUpTooLate(curTime, wakeUpTime);
1689     curWritePos = audioBuffer_->GetCurWriteFrame();
1690     if (!PrepareCurrentLoop(curWritePos)) {
1691         return true;
1692     }
1693     // call client write
1694     CallClientHandleCurrent();
1695     // client write done, check if time out
1696 
1697     DoFadeInOut(curWritePos);
1698 
1699     if (!FinishHandleCurrentLoop(curWritePos, clientWriteCost)) {
1700         return true;
1701     }
1702     if (!ClientPrepareNextLoop(curWritePos, wakeUpTime)) {
1703         return false;
1704     }
1705     traceLoop.End();
1706     // start safe sleep
1707     threadStatus_ = SLEEPING;
1708     CheckIfWakeUpTooLate(curTime, wakeUpTime, clientWriteCost);
1709     ClockTime::AbsoluteSleep(wakeUpTime);
1710     return true;
1711 }
1712 
ProcessCallbackFucIndependent()1713 void AudioProcessInClientInner::ProcessCallbackFucIndependent()
1714 {
1715     AUDIO_INFO_LOG("multi play loop start");
1716     processProxy_->RegisterThreadPriority(gettid(),
1717         AudioSystemManager::GetInstance()->GetSelfBundleName(processConfig_.appInfo.appUid));
1718     int64_t curTime = 0;
1719     uint64_t curWritePos = 0;
1720     int64_t wakeUpTime = ClockTime::GetCurNano();
1721     while (!isCallbackLoopEnd_) {
1722         if (!KeepLoopRunningIndependent()) {
1723             continue;
1724         }
1725         int32_t ret = 0;
1726         threadStatus_ = INRUNNING;
1727         curTime = ClockTime::GetCurNano();
1728         Trace traceLoop("AudioProcessInClient::InRunning");
1729         if (needReSyncPosition_) {
1730             UpdateHandleInfo(true, true);
1731             wakeUpTime = curTime;
1732             needReSyncPosition_ = false;
1733             continue;
1734         }
1735         curWritePos = audioBuffer_->GetCurWriteFrame();
1736         if (streamStatus_->load() == STREAM_RUNNING) {
1737             CallClientHandleCurrent();
1738         } else {
1739             AudioStreamData writeStreamData;
1740             ret = audioBuffer_->GetWriteBuffer(curWritePos, writeStreamData.bufferDesc);
1741             CHECK_AND_RETURN_LOG(ret == SUCCESS && writeStreamData.bufferDesc.buffer != nullptr,
1742                 "ret is fail or buffer is nullptr");
1743             memset_s(writeStreamData.bufferDesc.buffer, writeStreamData.bufferDesc.bufLength,
1744                 0, writeStreamData.bufferDesc.bufLength);
1745         }
1746         bool prepared = true;
1747         size_t round = (spanSizeInFrame_ == 0 ? 1 : clientSpanSizeInFrame_ / spanSizeInFrame_);
1748         for (size_t count = 0; count < round; count++) {
1749             if (!PrepareNextIndependent(curWritePos + count * spanSizeInFrame_, wakeUpTime)) {
1750                 prepared = false;
1751                 AUDIO_ERR_LOG("PrepareNextLoop failed!");
1752                 break;
1753             }
1754         }
1755         if (!prepared) {
1756             break;
1757         }
1758         traceLoop.End();
1759         // start sleep
1760         threadStatus_ = SLEEPING;
1761 
1762         ClockTime::AbsoluteSleep(wakeUpTime);
1763     }
1764 }
1765 
KeepLoopRunningIndependent()1766 bool AudioProcessInClientInner::KeepLoopRunningIndependent()
1767 {
1768     switch (streamStatus_->load()) {
1769         case STREAM_RUNNING:
1770             return true;
1771         case STREAM_IDEL:
1772             return true;
1773         case STREAM_PAUSED:
1774             return true;
1775         default:
1776             break;
1777     }
1778 
1779     return false;
1780 }
1781 
PrepareNextIndependent(uint64_t curWritePos,int64_t & wakeUpTime)1782 bool AudioProcessInClientInner::PrepareNextIndependent(uint64_t curWritePos, int64_t &wakeUpTime)
1783 {
1784     uint64_t nextHandlePos = curWritePos + spanSizeInFrame_;
1785     Trace prepareTrace("AudioEndpoint::PrepareNextLoop " + std::to_string(nextHandlePos));
1786     int64_t nextHdiReadTime = GetPredictNextHandleTime(nextHandlePos, true);
1787     uint64_t aheadTime = spanSizeInFrame_ * AUDIO_NS_PER_SECOND / processConfig_.streamInfo.samplingRate;
1788     int64_t nextServerHandleTime = nextHdiReadTime - static_cast<int64_t>(aheadTime);
1789     if (nextServerHandleTime < ClockTime::GetCurNano()) {
1790         wakeUpTime = ClockTime::GetCurNano() + ONE_MILLISECOND_DURATION; // make sure less than duration
1791     } else {
1792         wakeUpTime = nextServerHandleTime;
1793     }
1794 
1795     SpanInfo *nextWriteSpan = audioBuffer_->GetSpanInfo(nextHandlePos);
1796     if (nextWriteSpan == nullptr) {
1797         AUDIO_ERR_LOG("GetSpanInfo failed, can not get next write span");
1798         return false;
1799     }
1800 
1801     int32_t ret1 = audioBuffer_->SetCurWriteFrame(nextHandlePos);
1802     int32_t ret2 = audioBuffer_->SetCurReadFrame(nextHandlePos);
1803     if (ret1 != SUCCESS || ret2 != SUCCESS) {
1804         AUDIO_ERR_LOG("SetCurWriteFrame or SetCurReadFrame failed, ret1:%{public}d ret2:%{public}d", ret1, ret2);
1805         return false;
1806     }
1807     return true;
1808 }
1809 
CheckIfWakeUpTooLate(int64_t & curTime,int64_t & wakeUpTime)1810 void AudioProcessInClientInner::CheckIfWakeUpTooLate(int64_t &curTime, int64_t &wakeUpTime)
1811 {
1812     curTime = ClockTime::GetCurNano();
1813     int64_t wakeupCost = curTime - wakeUpTime;
1814     if (wakeupCost > ONE_MILLISECOND_DURATION) {
1815         if (wakeupCost > TWO_MILLISECOND_DURATION) {
1816             AUDIO_WARNING_LOG("loop wake up too late, cost %{public}" PRId64"us", wakeupCost / AUDIO_MS_PER_SECOND);
1817         }
1818         wakeUpTime = curTime;
1819     }
1820 }
1821 
CheckIfWakeUpTooLate(int64_t & curTime,int64_t & wakeUpTime,int64_t clientWriteCost)1822 void AudioProcessInClientInner::CheckIfWakeUpTooLate(int64_t &curTime, int64_t &wakeUpTime, int64_t clientWriteCost)
1823 {
1824     curTime = ClockTime::GetCurNano();
1825     int64_t round = static_cast<int64_t>(spanSizeInFrame_ == 0 ? 1 : clientSpanSizeInFrame_ / spanSizeInFrame_);
1826     int64_t clientBufferDurationInMs = static_cast<int64_t>(spanSizeInMs_) * ONE_MILLISECOND_DURATION * round;
1827     if (wakeUpTime - curTime > clientBufferDurationInMs + clientWriteCost) {
1828         Trace trace("BigWakeUpTime curTime[" + std::to_string(curTime) + "] target[" + std::to_string(wakeUpTime) +
1829             "] delay " + std::to_string(wakeUpTime - curTime) + "ns");
1830         AUDIO_PRERELEASE_LOGW("wakeUpTime is too late...");
1831     }
1832 }
1833 
SetDefaultOutputDevice(const DeviceType defaultOutputDevice)1834 int32_t AudioProcessInClientInner::SetDefaultOutputDevice(const DeviceType defaultOutputDevice)
1835 {
1836     CHECK_AND_RETURN_RET_LOG(processProxy_ != nullptr, ERR_OPERATION_FAILED, "set failed with null ipcProxy.");
1837     return processProxy_->SetDefaultOutputDevice(defaultOutputDevice);
1838 }
1839 
SetSilentModeAndMixWithOthers(bool on)1840 int32_t AudioProcessInClientInner::SetSilentModeAndMixWithOthers(bool on)
1841 {
1842     CHECK_AND_RETURN_RET_LOG(processProxy_ != nullptr, ERR_OPERATION_FAILED, "ipcProxy is null.");
1843     return processProxy_->SetSilentModeAndMixWithOthers(on);
1844 }
1845 
GetRestoreInfo(RestoreInfo & restoreInfo)1846 void AudioProcessInClientInner::GetRestoreInfo(RestoreInfo &restoreInfo)
1847 {
1848     CHECK_AND_RETURN_LOG(audioBuffer_ != nullptr, "Client OHAudioBuffer is nullptr");
1849     audioBuffer_->GetRestoreInfo(restoreInfo);
1850     return;
1851 }
1852 
SetRestoreInfo(RestoreInfo & restoreInfo)1853 void AudioProcessInClientInner::SetRestoreInfo(RestoreInfo &restoreInfo)
1854 {
1855     CHECK_AND_RETURN_LOG(audioBuffer_ != nullptr, "Client OHAudioBuffer is nullptr");
1856     audioBuffer_->SetRestoreInfo(restoreInfo);
1857     return;
1858 }
1859 
CheckRestoreStatus()1860 RestoreStatus AudioProcessInClientInner::CheckRestoreStatus()
1861 {
1862     CHECK_AND_RETURN_RET_LOG(audioBuffer_ != nullptr, RESTORE_ERROR, "Client OHAudioBuffer is nullptr");
1863     return audioBuffer_->CheckRestoreStatus();
1864 }
1865 
SetRestoreStatus(RestoreStatus restoreStatus)1866 RestoreStatus AudioProcessInClientInner::SetRestoreStatus(RestoreStatus restoreStatus)
1867 {
1868     CHECK_AND_RETURN_RET_LOG(audioBuffer_ != nullptr, RESTORE_ERROR, "Client OHAudioBuffer is nullptr");
1869     return audioBuffer_->SetRestoreStatus(restoreStatus);
1870 }
1871 } // namespace AudioStandard
1872 } // namespace OHOS
1873