• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 
16 #ifndef LOG_TAG
17 #define LOG_TAG "FastAudioCaptureSource"
18 #endif
19 
20 #include "source/fast_audio_capture_source.h"
21 #include <climits>
22 #include "audio_hdi_log.h"
23 #include "audio_errors.h"
24 #include "audio_utils.h"
25 #include "common/hdi_adapter_info.h"
26 #include "manager/hdi_adapter_manager.h"
27 
28 namespace OHOS {
29 namespace AudioStandard {
~FastAudioCaptureSource()30 FastAudioCaptureSource::~FastAudioCaptureSource()
31 {
32     AUDIO_INFO_LOG("destruction");
33 }
34 
Init(const IAudioSourceAttr & attr)35 int32_t FastAudioCaptureSource::Init(const IAudioSourceAttr &attr)
36 {
37     AUDIO_INFO_LOG("In, flag: %{public}d", attr.audioStreamFlag);
38     attr_ = attr;
39 
40     int32_t ret = CreateCapture();
41     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create capture fail");
42     ret = DoSetInputRoute(static_cast<DeviceType>(attr_.deviceType));
43     if (ret != SUCCESS) {
44         AUDIO_WARNING_LOG("update route fail, ret: %{public}d", ret);
45     }
46     ret = PrepareMmapBuffer();
47     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "prepare mmap buffer fail");
48     sourceInited_ = true;
49     return SUCCESS;
50 }
51 
DeInit(void)52 void FastAudioCaptureSource::DeInit(void)
53 {
54     AUDIO_INFO_LOG("in, flag: %{public}d, isCheckPositionSuccess: %{public}d", attr_.audioStreamFlag,
55         isCheckPositionSuccess_.load());
56     std::lock_guard<std::mutex> lock(statusMutex_);
57     if (started_ || !isCheckPositionSuccess_) {
58         Stop();
59         started_ = false;
60     }
61     sourceInited_ = false;
62     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
63     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
64     CHECK_AND_RETURN(deviceManager != nullptr);
65     deviceManager->DestroyCapture(attr_.adapterName, hdiCaptureId_);
66     audioCapture_ = nullptr;
67 
68     callback_.OnCaptureState(false);
69 }
70 
IsInited(void)71 bool FastAudioCaptureSource::IsInited(void)
72 {
73     return sourceInited_;
74 }
75 
Start(void)76 int32_t FastAudioCaptureSource::Start(void)
77 {
78     std::lock_guard<std::mutex> lock(statusMutex_);
79     AUDIO_INFO_LOG("in");
80 #ifdef FEATURE_POWER_MANAGER
81     if (runningLock_ == nullptr) {
82         WatchTimeout guard("create AudioRunningLock start");
83         runningLock_ = std::make_shared<AudioRunningLock>(std::string(RUNNING_LOCK_NAME));
84         guard.CheckCurrTimeout();
85     }
86     if (runningLock_ != nullptr) {
87         runningLock_->Lock(RUNNING_LOCK_TIMEOUTMS_LASTING);
88     } else {
89         AUDIO_ERR_LOG("running lock is null, playback can not work well");
90     }
91 #endif
92     if (started_) {
93         isCheckPositionSuccess_ = true;
94         return SUCCESS;
95     }
96     callback_.OnCaptureState(true);
97     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
98     int32_t ret = audioCapture_->Start(audioCapture_);
99     if (ret != SUCCESS) {
100         goto ERR_RET;
101     }
102     ret = CheckPositionTime();
103     if (ret != SUCCESS) {
104         isCheckPositionSuccess_ = false;
105         goto ERR_RET;
106     }
107     isCheckPositionSuccess_ = true;
108     started_ = true;
109     return SUCCESS;
110 
111 ERR_RET:
112     callback_.OnCaptureState(false);
113     return ERR_NOT_STARTED;
114 }
115 
Stop(void)116 int32_t FastAudioCaptureSource::Stop(void)
117 {
118     std::lock_guard<std::mutex> lock(statusMutex_);
119     AUDIO_INFO_LOG("in, isCheckPositionSuccess: %{public}d", isCheckPositionSuccess_.load());
120 
121 #ifdef FEATURE_POWER_MANAGER
122     if (runningLock_ != nullptr) {
123         AUDIO_INFO_LOG("running lock unlock");
124         runningLock_->UnLock();
125     } else {
126         AUDIO_WARNING_LOG("running lock is null, playback can not work well");
127     }
128 #endif
129     if (!started_) {
130         return SUCCESS;
131     }
132     if (isCheckPositionSuccess_) {
133         CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
134         int32_t ret = audioCapture_->Stop(audioCapture_);
135         callback_.OnCaptureState(false);
136         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "stop fail, ret: %{public}d", ret);
137     }
138     started_ = false;
139     return SUCCESS;
140 }
141 
Resume(void)142 int32_t FastAudioCaptureSource::Resume(void)
143 {
144     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
145 
146     if (!paused_) {
147         return SUCCESS;
148     }
149     int32_t ret = audioCapture_->Resume(audioCapture_);
150     callback_.OnCaptureState(true);
151     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "resume fail");
152     paused_ = false;
153     return SUCCESS;
154 }
155 
Pause(void)156 int32_t FastAudioCaptureSource::Pause(void)
157 {
158     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
159     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
160 
161     int32_t ret = audioCapture_->Pause(audioCapture_);
162     callback_.OnCaptureState(false);
163     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "pause fail");
164     paused_ = true;
165     return SUCCESS;
166 }
167 
Flush(void)168 int32_t FastAudioCaptureSource::Flush(void)
169 {
170     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
171     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
172 
173     int32_t ret = audioCapture_->Flush(audioCapture_);
174     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "flush fail");
175     return SUCCESS;
176 }
177 
Reset(void)178 int32_t FastAudioCaptureSource::Reset(void)
179 {
180     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
181     CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state");
182 
183     int32_t ret = audioCapture_->Flush(audioCapture_);
184     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "reset fail");
185     return SUCCESS;
186 }
187 
CaptureFrame(char * frame,uint64_t requestBytes,uint64_t & replyBytes)188 int32_t FastAudioCaptureSource::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes)
189 {
190     AUDIO_INFO_LOG("not support");
191     return ERR_NOT_SUPPORTED;
192 }
193 
CaptureFrameWithEc(FrameDesc * fdesc,uint64_t & replyBytes,FrameDesc * fdescEc,uint64_t & replyBytesEc)194 int32_t FastAudioCaptureSource::CaptureFrameWithEc(FrameDesc *fdesc, uint64_t &replyBytes, FrameDesc *fdescEc,
195     uint64_t &replyBytesEc)
196 {
197     AUDIO_INFO_LOG("not support");
198     return ERR_NOT_SUPPORTED;
199 }
200 
GetAudioParameter(const AudioParamKey key,const std::string & condition)201 std::string FastAudioCaptureSource::GetAudioParameter(const AudioParamKey key, const std::string &condition)
202 {
203     return "";
204 }
205 
SetVolume(float left,float right)206 int32_t FastAudioCaptureSource::SetVolume(float left, float right)
207 {
208     AUDIO_INFO_LOG("not support");
209     return ERR_NOT_SUPPORTED;
210 }
211 
GetVolume(float & left,float & right)212 int32_t FastAudioCaptureSource::GetVolume(float &left, float &right)
213 {
214     AUDIO_INFO_LOG("not support");
215     return ERR_NOT_SUPPORTED;
216 }
217 
SetMute(bool isMute)218 int32_t FastAudioCaptureSource::SetMute(bool isMute)
219 {
220     AUDIO_INFO_LOG("not support");
221     return ERR_NOT_SUPPORTED;
222 }
223 
GetMute(bool & isMute)224 int32_t FastAudioCaptureSource::GetMute(bool &isMute)
225 {
226     AUDIO_INFO_LOG("not support");
227     return ERR_NOT_SUPPORTED;
228 }
229 
GetTransactionId(void)230 uint64_t FastAudioCaptureSource::GetTransactionId(void)
231 {
232     return reinterpret_cast<uint64_t>(audioCapture_);
233 }
234 
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)235 int32_t FastAudioCaptureSource::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
236 {
237     AUDIO_INFO_LOG("not support");
238     return ERR_NOT_SUPPORTED;
239 }
240 
GetMaxAmplitude(void)241 float FastAudioCaptureSource::GetMaxAmplitude(void)
242 {
243     AUDIO_INFO_LOG("not support");
244     return 0;
245 }
246 
SetAudioScene(AudioScene audioScene,bool scoExcludeFlag)247 int32_t FastAudioCaptureSource::SetAudioScene(AudioScene audioScene, bool scoExcludeFlag)
248 {
249     CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene < AUDIO_SCENE_MAX, ERR_INVALID_PARAM,
250         "invalid scene");
251     AUDIO_INFO_LOG("scene: %{public}d", audioScene);
252 
253     if (audioScene != currentAudioScene_) {
254         struct AudioSceneDescriptor sceneDesc;
255         InitSceneDesc(sceneDesc, audioScene);
256 
257         CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
258         int32_t ret = audioCapture_->SelectScene(audioCapture_, &sceneDesc);
259         CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_OPERATION_FAILED, "select scene fail, ret: %{public}d", ret);
260         currentAudioScene_ = audioScene;
261     }
262     return SUCCESS;
263 }
264 
UpdateActiveDevice(DeviceType inputDevice)265 int32_t FastAudioCaptureSource::UpdateActiveDevice(DeviceType inputDevice)
266 {
267     return DoSetInputRoute(inputDevice);
268 }
269 
RegistCallback(uint32_t type,std::shared_ptr<IAudioSourceCallback> callback)270 void FastAudioCaptureSource::RegistCallback(uint32_t type, std::shared_ptr<IAudioSourceCallback> callback)
271 {
272     AUDIO_INFO_LOG("in");
273     callback_.RegistCallback(type, callback);
274 }
275 
UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE],const size_t size)276 int32_t FastAudioCaptureSource::UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE], const size_t size)
277 {
278 #ifdef FEATURE_POWER_MANAGER
279     CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr");
280     runningLock_->UpdateAppsUid(appsUid, appsUid + size);
281 #endif
282     return SUCCESS;
283 }
284 
UpdateAppsUid(const std::vector<int32_t> & appsUid)285 int32_t FastAudioCaptureSource::UpdateAppsUid(const std::vector<int32_t> &appsUid)
286 {
287 #ifdef FEATURE_POWER_MANAGER
288     CHECK_AND_RETURN_RET_LOG(runningLock_, ERR_INVALID_HANDLE, "running lock is nullptr");
289     runningLock_->UpdateAppsUid(appsUid.cbegin(), appsUid.cend());
290     runningLock_->UpdateAppsUidToPowerMgr();
291 #endif
292     return SUCCESS;
293 }
294 
DumpInfo(std::string & dumpString)295 void FastAudioCaptureSource::DumpInfo(std::string &dumpString)
296 {
297     dumpString += "type: FastSource\tstarted: " + std::string(started_ ? "true" : "false") + "\n";
298 }
299 
GetMmapBufferInfo(int & fd,uint32_t & totalSizeInframe,uint32_t & spanSizeInframe,uint32_t & byteSizePerFrame,uint32_t & syncInfoSize)300 int32_t FastAudioCaptureSource::GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe,
301     uint32_t &byteSizePerFrame, uint32_t &syncInfoSize)
302 {
303     CHECK_AND_RETURN_RET_LOG(bufferFd_ != INVALID_FD, ERR_INVALID_HANDLE, "buffer fd has been released");
304     fd = bufferFd_;
305     totalSizeInframe = bufferTotalFrameSize_;
306     spanSizeInframe = eachReadFrameSize_;
307     byteSizePerFrame = PcmFormatToBit(attr_.format) * attr_.channel / PCM_8_BIT;
308     syncInfoSize = syncInfoSize_;
309     return SUCCESS;
310 }
311 
GetMmapHandlePosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)312 int32_t FastAudioCaptureSource::GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
313 {
314     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
315 
316     struct AudioTimeStamp stamp = {};
317     int32_t ret = audioCapture_->GetMmapPosition(audioCapture_, &frames, &stamp);
318     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get mmap position fail, ret: %{public}d", ret);
319 
320     int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it
321     CHECK_AND_RETURN_RET_LOG(stamp.tvSec >= 0 && stamp.tvSec <= maxSec && stamp.tvNSec >= 0 &&
322         stamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED,
323         "get invalid time, second: %{public}" PRId64 ", nanosecond: %{public}" PRId64, stamp.tvSec, stamp.tvNSec);
324     timeSec = stamp.tvSec;
325     timeNanoSec = stamp.tvNSec;
326     return ret;
327 }
328 
PcmFormatToBit(AudioSampleFormat format)329 uint32_t FastAudioCaptureSource::PcmFormatToBit(AudioSampleFormat format)
330 {
331     switch (format) {
332         case SAMPLE_U8:
333             return PCM_8_BIT;
334         case SAMPLE_S16LE:
335             return PCM_16_BIT;
336         case SAMPLE_S24LE:
337             return PCM_24_BIT;
338         case SAMPLE_S32LE:
339             return PCM_32_BIT;
340         case SAMPLE_F32LE:
341             return PCM_32_BIT;
342         default:
343             AUDIO_DEBUG_LOG("unknown format type, set it to default");
344             return PCM_24_BIT;
345     }
346 }
347 
ConvertToHdiFormat(AudioSampleFormat format)348 AudioFormat FastAudioCaptureSource::ConvertToHdiFormat(AudioSampleFormat format)
349 {
350     AudioFormat hdiFormat;
351     switch (format) {
352         case SAMPLE_U8:
353             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
354             break;
355         case SAMPLE_S16LE:
356             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
357             break;
358         case SAMPLE_S24LE:
359             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
360             break;
361         case SAMPLE_S32LE:
362             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
363             break;
364         default:
365             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
366             break;
367     }
368     return hdiFormat;
369 }
370 
ConvertToHDIAudioInputType(int32_t sourceType)371 enum AudioInputType FastAudioCaptureSource::ConvertToHDIAudioInputType(int32_t sourceType)
372 {
373     enum AudioInputType hdiAudioInputType;
374     switch (sourceType) {
375         case SOURCE_TYPE_INVALID:
376             hdiAudioInputType = AUDIO_INPUT_DEFAULT_TYPE;
377             break;
378         case SOURCE_TYPE_MIC:
379         case SOURCE_TYPE_PLAYBACK_CAPTURE:
380         case SOURCE_TYPE_ULTRASONIC:
381         case SOURCE_TYPE_UNPROCESSED:
382         case SOURCE_TYPE_LIVE:
383             hdiAudioInputType = AUDIO_INPUT_MIC_TYPE;
384             break;
385         case SOURCE_TYPE_WAKEUP:
386             hdiAudioInputType = AUDIO_INPUT_SPEECH_WAKEUP_TYPE;
387             break;
388         case SOURCE_TYPE_VOICE_COMMUNICATION:
389             hdiAudioInputType = AUDIO_INPUT_VOICE_COMMUNICATION_TYPE;
390             break;
391         case SOURCE_TYPE_VOICE_RECOGNITION:
392             hdiAudioInputType = AUDIO_INPUT_VOICE_RECOGNITION_TYPE;
393             break;
394         case SOURCE_TYPE_VOICE_CALL:
395             hdiAudioInputType = AUDIO_INPUT_VOICE_CALL_TYPE;
396             break;
397         case SOURCE_TYPE_CAMCORDER:
398             hdiAudioInputType = AUDIO_INPUT_CAMCORDER_TYPE;
399             break;
400         default:
401             hdiAudioInputType = AUDIO_INPUT_MIC_TYPE;
402             break;
403     }
404     return hdiAudioInputType;
405 }
406 
GetAudioCategory(AudioScene audioScene)407 AudioCategory FastAudioCaptureSource::GetAudioCategory(AudioScene audioScene)
408 {
409     AudioCategory audioCategory;
410     switch (audioScene) {
411         case AUDIO_SCENE_DEFAULT:
412             audioCategory = AUDIO_IN_MEDIA;
413             break;
414         case AUDIO_SCENE_RINGING:
415         case AUDIO_SCENE_VOICE_RINGING:
416             audioCategory = AUDIO_IN_RINGTONE;
417             break;
418         case AUDIO_SCENE_PHONE_CALL:
419             audioCategory = AUDIO_IN_CALL;
420             break;
421         case AUDIO_SCENE_PHONE_CHAT:
422             audioCategory = AUDIO_IN_COMMUNICATION;
423             break;
424         default:
425             audioCategory = AUDIO_IN_MEDIA;
426             break;
427     }
428     AUDIO_DEBUG_LOG("audioCategory: %{public}d", audioCategory);
429 
430     return audioCategory;
431 }
432 
InitAudioSampleAttr(struct AudioSampleAttributes & param)433 void FastAudioCaptureSource::InitAudioSampleAttr(struct AudioSampleAttributes &param)
434 {
435     param.format = AUDIO_FORMAT_TYPE_PCM_16_BIT;
436     param.channelCount = AUDIO_CHANNELCOUNT;
437     param.interleaved = true;
438     param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_CAPTURE_ID_BASE, HDI_CAPTURE_OFFSET_FAST));
439     param.period = 0;
440     param.frameSize = PCM_16_BIT * param.channelCount / PCM_8_BIT;
441     param.isBigEndian = false;
442     param.isSignedData = true;
443     param.startThreshold = 0;
444     param.stopThreshold = INT_MAX;
445     param.silenceThreshold = 0;
446 
447     param.sourceType = static_cast<int32_t>(ConvertToHDIAudioInputType(attr_.sourceType));
448     param.type = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ? AUDIO_MMAP_VOIP : AUDIO_MMAP_NOIRQ; // enable mmap!
449     param.sampleRate = attr_.sampleRate;
450     param.format = ConvertToHdiFormat(attr_.format);
451     param.isBigEndian = attr_.isBigEndian;
452     param.channelCount = attr_.channel;
453     if (param.channelCount == MONO) {
454         param.channelLayout = CH_LAYOUT_MONO;
455     } else if (param.channelCount == STEREO) {
456         param.channelLayout = CH_LAYOUT_STEREO;
457     }
458     param.silenceThreshold = attr_.bufferSize;
459     param.frameSize = param.format * param.channelCount;
460     param.startThreshold = 0;
461 }
462 
InitDeviceDesc(struct AudioDeviceDescriptor & deviceDesc)463 void FastAudioCaptureSource::InitDeviceDesc(struct AudioDeviceDescriptor &deviceDesc)
464 {
465     switch (static_cast<DeviceType>(attr_.deviceType)) {
466         case DEVICE_TYPE_MIC:
467             deviceDesc.pins = PIN_IN_MIC;
468             break;
469         case DEVICE_TYPE_WIRED_HEADSET:
470             deviceDesc.pins = PIN_IN_HS_MIC;
471             break;
472         case DEVICE_TYPE_USB_HEADSET:
473             deviceDesc.pins = PIN_IN_USB_EXT;
474             break;
475         case DEVICE_TYPE_BLUETOOTH_SCO:
476             deviceDesc.pins = PIN_IN_BLUETOOTH_SCO_HEADSET;
477             break;
478         default:
479             AUDIO_WARNING_LOG("unsupport, use default, deviceType: %{public}d", attr_.deviceType);
480             deviceDesc.pins = PIN_IN_MIC;
481             break;
482     }
483     deviceDesc.desc = const_cast<char *>("");
484 }
485 
InitSceneDesc(struct AudioSceneDescriptor & sceneDesc,AudioScene audioScene)486 void FastAudioCaptureSource::InitSceneDesc(struct AudioSceneDescriptor &sceneDesc, AudioScene audioScene)
487 {
488     sceneDesc.scene.id = GetAudioCategory(audioScene);
489     sceneDesc.desc.pins = PIN_IN_BLUETOOTH_SCO_HEADSET;
490     sceneDesc.desc.desc = const_cast<char *>("pin_in_bluetooth_sco_headset");
491 }
492 
CreateCapture(void)493 int32_t FastAudioCaptureSource::CreateCapture(void)
494 {
495     struct AudioSampleAttributes param;
496     struct AudioDeviceDescriptor deviceDesc;
497     InitAudioSampleAttr(param);
498     InitDeviceDesc(deviceDesc);
499 
500     AUDIO_INFO_LOG("create capture, type: %{public}d, rate: %{public}u, channel: %{public}u, format: %{public}u, "
501         "device: %{public}u", param.type, param.sampleRate, param.channelCount, param.format, attr_.deviceType);
502     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
503     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
504     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
505     void *capture = deviceManager->CreateCapture(attr_.adapterName, &param, &deviceDesc, hdiCaptureId_);
506     audioCapture_ = static_cast<struct IAudioCapture *>(capture);
507     CHECK_AND_RETURN_RET(audioCapture_ != nullptr, ERR_NOT_STARTED);
508 
509     return SUCCESS;
510 }
511 
DoSetInputRoute(DeviceType inputDevice)512 int32_t FastAudioCaptureSource::DoSetInputRoute(DeviceType inputDevice)
513 {
514     HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
515     std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_LOCAL);
516     CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
517     int32_t streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_CAPTURE_ID_BASE, HDI_CAPTURE_OFFSET_FAST));
518     int32_t inputType = static_cast<int32_t>(ConvertToHDIAudioInputType(attr_.sourceType));
519     AUDIO_INFO_LOG("adapterName: %{public}s, inputDevice: %{public}d, streamId: %{public}d, input :%{public}d",
520         attr_.adapterName.c_str(), inputDevice, streamId, inputType);
521     int32_t ret = deviceManager->SetInputRoute(attr_.adapterName, inputDevice, streamId, inputType);
522     return ret;
523 }
524 
PrepareMmapBuffer(void)525 int32_t FastAudioCaptureSource::PrepareMmapBuffer(void)
526 {
527     uint32_t totalBufferInMs = 40; // 40: 5 * (6 + 2 * (1)) = 40ms, the buffer size, not latency
528     uint32_t reqBufferFrameSize = totalBufferInMs * (attr_.sampleRate / SECOND_TO_MILLISECOND);
529     struct AudioMmapBufferDescriptor desc;
530     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
531 
532     int32_t ret = audioCapture_->ReqMmapBuffer(audioCapture_, reqBufferFrameSize, &desc);
533     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "request mmap buffer fail, ret: %{public}d", ret);
534     AUDIO_INFO_LOG("memoryFd: [%{public}d], totalBufferFrames: [%{public}d], "
535         "transferFrameSize: [%{public}d], isShareable: [%{public}d], offset: [%{public}d]", desc.memoryFd,
536         desc.totalBufferFrames, desc.transferFrameSize, desc.isShareable, desc.offset);
537 
538     bufferFd_ = desc.memoryFd; // fcntl(fd, 1030, 3) after dup?
539     int32_t periodFrameMaxSize = 1920000; // 192khz * 10s
540     CHECK_AND_RETURN_RET_LOG(desc.totalBufferFrames >= 0 && desc.transferFrameSize >= 0 &&
541         desc.transferFrameSize <= periodFrameMaxSize, ERR_OPERATION_FAILED,
542         "invalid value, totalBufferFrames: [%{public}d], transferFrameSize: [%{public}d]", desc.totalBufferFrames,
543         desc.transferFrameSize);
544 
545     uint32_t frameSizeInByte = PcmFormatToBit(attr_.format) * attr_.channel / PCM_8_BIT;
546     bufferTotalFrameSize_ = static_cast<uint32_t>(desc.totalBufferFrames); // 1440 ~ 3840
547     eachReadFrameSize_ = static_cast<uint32_t>(desc.transferFrameSize); // 240
548     CHECK_AND_RETURN_RET_LOG(frameSizeInByte <= ULLONG_MAX / bufferTotalFrameSize_, ERR_OPERATION_FAILED,
549         "buffer size will overflow");
550 
551     bufferSize_ = bufferTotalFrameSize_ * frameSizeInByte;
552     return SUCCESS;
553 }
554 
CheckPositionTime(void)555 int32_t FastAudioCaptureSource::CheckPositionTime(void)
556 {
557     int32_t tryCount = MAX_GET_POSITION_TRY_COUNT;
558     uint64_t frames = 0;
559     int64_t timeSec = 0;
560     int64_t timeNanoSec = 0;
561     int64_t maxHandleTime = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ? VOIP_MAX_GET_POSITION_HANDLE_TIME :
562         GENERAL_MAX_GET_POSITION_HANDLE_TIME;
563     while (tryCount-- > 0) {
564         ClockTime::RelativeSleep(MAX_GET_POSITION_WAIT_TIME);
565         int32_t ret = GetMmapHandlePosition(frames, timeSec, timeNanoSec);
566         int64_t curTime = ClockTime::GetCurNano();
567         int64_t curSec = curTime / AUDIO_NS_PER_SECOND;
568         int64_t curNanoSec = curTime - curSec * AUDIO_NS_PER_SECOND;
569         AUDIO_WARNING_LOG("sec: %{public}" PRId64 ", nanoSec: %{public}" PRId64 ", time cost: %{public}" PRId64,
570             timeSec, timeNanoSec, ClockTime::GetCurNano() - curTime);
571         if (ret != SUCCESS || curSec != timeSec || curNanoSec - timeNanoSec > maxHandleTime) {
572             AUDIO_WARNING_LOG("tryCount: %{public}d, ret: %{public}d", tryCount, ret);
573             continue;
574         } else {
575             AUDIO_INFO_LOG("check succ");
576             return SUCCESS;
577         }
578     }
579 #ifdef FEATURE_POWER_MANAGER
580     if (runningLock_ != nullptr) {
581         AUDIO_INFO_LOG("running lock unlock");
582         runningLock_->UnLock();
583     } else {
584         AUDIO_WARNING_LOG("running lock is null, playback can not work well");
585     }
586 #endif
587     AUDIO_ERR_LOG("fail, stop capture");
588     CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
589     int32_t ret = audioCapture_->Stop(audioCapture_);
590     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "stop fail, ret: %{public}d", ret);
591     return ERR_OPERATION_FAILED;
592 }
593 
SetDmDeviceType(uint16_t dmDeviceType,DeviceType deviceType)594 void FastAudioCaptureSource::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType)
595 {
596     AUDIO_INFO_LOG("not support");
597 }
598 
599 } // namespace AudioStandard
600 } // namespace OHOS
601