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