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