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 "RemoteFastAudioCaptureSource"
18 #endif
19
20 #include "source/remote_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 using namespace OHOS::HDI::DistributedAudio::Audio::V1_0;
29
30 namespace OHOS {
31 namespace AudioStandard {
RemoteFastAudioCaptureSource(const std::string & deviceNetworkId)32 RemoteFastAudioCaptureSource::RemoteFastAudioCaptureSource(const std::string &deviceNetworkId)
33 : deviceNetworkId_(deviceNetworkId)
34 {
35 AUDIO_INFO_LOG("construction");
36 }
37
~RemoteFastAudioCaptureSource()38 RemoteFastAudioCaptureSource::~RemoteFastAudioCaptureSource()
39 {
40 AUDIO_INFO_LOG("destruction");
41 if (sourceInited_.load()) {
42 DeInit();
43 }
44 AUDIO_INFO_LOG("end");
45 }
46
Init(const IAudioSourceAttr & attr)47 int32_t RemoteFastAudioCaptureSource::Init(const IAudioSourceAttr &attr)
48 {
49 AUDIO_INFO_LOG("in");
50 attr_ = attr;
51
52 if (!captureInited_.load()) {
53 int32_t ret = CreateCapture();
54 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create capture fail");
55 }
56
57 captureInited_.store(true);
58 sourceInited_.store(true);
59
60 #ifdef DEBUG_DIRECT_USE_HDI
61 AUDIO_INFO_LOG("attr: [%{public}s]", PrintAttr().c_str());
62 dumpFile_ = fopen(dumpFileName_, "a+");
63 AUDIO_INFO_LOG("dumpFileName: %{public}s", dumpFileName_);
64 if (dumpFile_ == nullptr) {
65 AUDIO_WARNING_LOG("open dump file fail");
66 }
67 #endif
68 AUDIO_INFO_LOG("end");
69 return SUCCESS;
70 }
71
DeInit(void)72 void RemoteFastAudioCaptureSource::DeInit(void)
73 {
74 AUDIO_INFO_LOG("in");
75 sourceInited_.store(false);
76 captureInited_.store(false);
77 started_.store(false);
78 paused_.store(false);
79 muteState_.store(false);
80
81 #ifdef DEBUG_DIRECT_USE_HDI
82 if (dumpFile_) {
83 fclose(dumpFile_);
84 dumpFile_ = nullptr;
85 }
86 if (ashmemSource_ != nullptr) {
87 ashmemSource_->UnmapAshmem();
88 ashmemSource_->CloseAshmem();
89 ashmemSource_ = nullptr;
90 AUDIO_INFO_LOG("deinit ashmem source succ");
91 }
92 #endif
93
94 if (bufferFd_ != INVALID_FD) {
95 CloseFd(bufferFd_);
96 bufferFd_ = INVALID_FD;
97 }
98
99 HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
100 std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
101 CHECK_AND_RETURN(deviceManager != nullptr);
102 deviceManager->DestroyCapture(deviceNetworkId_, hdiCaptureId_);
103 deviceManager->UnRegistCaptureSourceCallback(deviceNetworkId_, hdiCaptureId_);
104 audioCapture_.ForceSetRefPtr(nullptr);
105 AUDIO_DEBUG_LOG("end");
106 }
107
IsInited(void)108 bool RemoteFastAudioCaptureSource::IsInited(void)
109 {
110 return sourceInited_.load();
111 }
112
Start(void)113 int32_t RemoteFastAudioCaptureSource::Start(void)
114 {
115 AUDIO_INFO_LOG("in");
116 if (!captureInited_.load()) {
117 int32_t ret = CreateCapture();
118 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "create capture fail");
119 captureInited_.store(true);
120 }
121 if (started_.load()) {
122 AUDIO_INFO_LOG("already start");
123 return SUCCESS;
124 }
125
126 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
127 int32_t ret = audioCapture_->Start();
128 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "start fail, ret: %{public}d", ret);
129 ret = CheckPositionTime();
130 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "check position time fail, ret: %{public}d", ret);
131 started_.store(true);
132 return SUCCESS;
133 }
134
Stop(void)135 int32_t RemoteFastAudioCaptureSource::Stop(void)
136 {
137 AUDIO_INFO_LOG("in");
138 if (!started_.load()) {
139 AUDIO_INFO_LOG("already stop");
140 return SUCCESS;
141 }
142
143 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
144 int32_t ret = audioCapture_->Stop();
145 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "stop fail, ret: %{public}d", ret);
146 started_.store(false);
147 return SUCCESS;
148 }
149
Resume(void)150 int32_t RemoteFastAudioCaptureSource::Resume(void)
151 {
152 AUDIO_INFO_LOG("in");
153 CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
154
155 if (!paused_.load()) {
156 AUDIO_INFO_LOG("already resume");
157 return SUCCESS;
158 }
159
160 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
161 int32_t ret = audioCapture_->Resume();
162 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "resume fail, ret: %{public}d", ret);
163 paused_.store(false);
164 return SUCCESS;
165 }
166
Pause(void)167 int32_t RemoteFastAudioCaptureSource::Pause(void)
168 {
169 AUDIO_INFO_LOG("in");
170 CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
171
172 if (paused_.load()) {
173 AUDIO_INFO_LOG("already pause");
174 return SUCCESS;
175 }
176
177 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
178 int32_t ret = audioCapture_->Pause();
179 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "pause fail, ret: %{public}d", ret);
180 paused_.store(true);
181 return SUCCESS;
182 }
183
Flush(void)184 int32_t RemoteFastAudioCaptureSource::Flush(void)
185 {
186 AUDIO_INFO_LOG("in");
187 CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
188
189 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
190 int32_t ret = audioCapture_->Flush();
191 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "flush fail, ret: %{public}d", ret);
192 return SUCCESS;
193 }
194
Reset(void)195 int32_t RemoteFastAudioCaptureSource::Reset(void)
196 {
197 AUDIO_INFO_LOG("in");
198 CHECK_AND_RETURN_RET_LOG(started_.load(), ERR_ILLEGAL_STATE, "not start, invalid state");
199
200 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
201 int32_t ret = audioCapture_->Flush();
202 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_NOT_STARTED, "reset fail, ret: %{public}d", ret);
203 return SUCCESS;
204 }
205
CaptureFrame(char * frame,uint64_t requestBytes,uint64_t & replyBytes)206 int32_t RemoteFastAudioCaptureSource::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes)
207 {
208 AUDIO_INFO_LOG("not support");
209 return SUCCESS;
210 }
211
CaptureFrameWithEc(FrameDesc * fdesc,uint64_t & replyBytes,FrameDesc * fdescEc,uint64_t & replyBytesEc)212 int32_t RemoteFastAudioCaptureSource::CaptureFrameWithEc(FrameDesc *fdesc, uint64_t &replyBytes, FrameDesc *fdescEc,
213 uint64_t &replyBytesEc)
214 {
215 AUDIO_INFO_LOG("not support");
216 return SUCCESS;
217 }
218
GetAudioParameter(const AudioParamKey key,const std::string & condition)219 std::string RemoteFastAudioCaptureSource::GetAudioParameter(const AudioParamKey key, const std::string &condition)
220 {
221 return "";
222 }
223
SetVolume(float left,float right)224 int32_t RemoteFastAudioCaptureSource::SetVolume(float left, float right)
225 {
226 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
227
228 AUDIO_INFO_LOG("left: %{public}f, right: %{public}f", left, right);
229 leftVolume_ = left;
230 rightVolume_ = right;
231 float volume;
232 if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
233 volume = rightVolume_;
234 } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
235 volume = leftVolume_;
236 } else {
237 volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
238 }
239
240 int32_t ret = audioCapture_->SetVolume(volume);
241 if (ret != SUCCESS) {
242 AUDIO_WARNING_LOG("set volume fail");
243 }
244
245 return ret;
246 }
247
GetVolume(float & left,float & right)248 int32_t RemoteFastAudioCaptureSource::GetVolume(float &left, float &right)
249 {
250 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
251
252 float val = 0.0;
253 audioCapture_->GetVolume(val);
254 left = val;
255 right = val;
256 return SUCCESS;
257 }
258
SetMute(bool isMute)259 int32_t RemoteFastAudioCaptureSource::SetMute(bool isMute)
260 {
261 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
262 int32_t ret = audioCapture_->SetMute(isMute);
263 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "set mute fail");
264 muteState_ = isMute;
265 return SUCCESS;
266 }
267
GetMute(bool & isMute)268 int32_t RemoteFastAudioCaptureSource::GetMute(bool &isMute)
269 {
270 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
271 bool hdiMuteState = false;
272 int32_t ret = audioCapture_->GetMute(hdiMuteState);
273 if (ret != SUCCESS) {
274 AUDIO_WARNING_LOG("get mute fail");
275 }
276 AUDIO_DEBUG_LOG("hdiMuteState: %{public}d, muteState: %{public}d", hdiMuteState, muteState_.load());
277 isMute = muteState_;
278 return SUCCESS;
279 }
280
GetTransactionId(void)281 uint64_t RemoteFastAudioCaptureSource::GetTransactionId(void)
282 {
283 AUDIO_INFO_LOG("not support");
284 return ERR_NOT_SUPPORTED;
285 }
286
GetPresentationPosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)287 int32_t RemoteFastAudioCaptureSource::GetPresentationPosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
288 {
289 AUDIO_INFO_LOG("not support");
290 return ERR_NOT_SUPPORTED;
291 }
292
GetMaxAmplitude(void)293 float RemoteFastAudioCaptureSource::GetMaxAmplitude(void)
294 {
295 AUDIO_INFO_LOG("not support");
296 return 0;
297 }
298
SetAudioScene(AudioScene audioScene,bool scoExcludeFlag)299 int32_t RemoteFastAudioCaptureSource::SetAudioScene(AudioScene audioScene, bool scoExcludeFlag)
300 {
301 CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene < AUDIO_SCENE_MAX, ERR_INVALID_PARAM,
302 "invalid scene");
303 AUDIO_INFO_LOG("scene: %{public}d", audioScene);
304
305 struct AudioSceneDescriptor sceneDesc;
306 InitSceneDesc(sceneDesc, audioScene);
307 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
308 int32_t ret = audioCapture_->SelectScene(sceneDesc);
309 CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_OPERATION_FAILED, "select scene fail, ret: %{public}d", ret);
310 return SUCCESS;
311 }
312
UpdateActiveDevice(DeviceType inputDevice)313 int32_t RemoteFastAudioCaptureSource::UpdateActiveDevice(DeviceType inputDevice)
314 {
315 AUDIO_INFO_LOG("not support");
316 return ERR_NOT_SUPPORTED;
317 }
318
RegistCallback(uint32_t type,IAudioSourceCallback * callback)319 void RemoteFastAudioCaptureSource::RegistCallback(uint32_t type, IAudioSourceCallback *callback)
320 {
321 AUDIO_INFO_LOG("in");
322 callback_.RegistCallback(type, callback);
323 }
324
UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE],const size_t size)325 int32_t RemoteFastAudioCaptureSource::UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE], const size_t size)
326 {
327 return ERR_NOT_SUPPORTED;
328 }
329
UpdateAppsUid(const std::vector<int32_t> & appsUid)330 int32_t RemoteFastAudioCaptureSource::UpdateAppsUid(const std::vector<int32_t> &appsUid)
331 {
332 return ERR_NOT_SUPPORTED;
333 }
334
DumpInfo(std::string & dumpString)335 void RemoteFastAudioCaptureSource::DumpInfo(std::string &dumpString)
336 {
337 dumpString += "type: RemoteFastSource\tstarted: " + std::string(started_.load() ? "true" : "false") +
338 "\tdeviceNetworkId: " + deviceNetworkId_ + "\n";
339 }
340
OnAudioParamChange(const std::string & adapterName,const AudioParamKey key,const std::string & condition,const std::string & value)341 void RemoteFastAudioCaptureSource::OnAudioParamChange(const std::string &adapterName, const AudioParamKey key,
342 const std::string &condition, const std::string &value)
343 {
344 AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, value: %{public}s", key, condition.c_str(), value.c_str());
345 if (key == AudioParamKey::PARAM_KEY_STATE) {
346 DeInit();
347 }
348
349 callback_.OnCaptureSourceParamChange(adapterName, key, condition, value);
350 }
351
GetMmapBufferInfo(int & fd,uint32_t & totalSizeInframe,uint32_t & spanSizeInframe,uint32_t & byteSizePerFrame,uint32_t & syncInfoSize)352 int32_t RemoteFastAudioCaptureSource::GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe, uint32_t &spanSizeInframe,
353 uint32_t &byteSizePerFrame, uint32_t &syncInfoSize)
354 {
355 CHECK_AND_RETURN_RET_LOG(bufferFd_ != INVALID_FD, ERR_INVALID_HANDLE, "buffer fd has been released");
356 fd = bufferFd_;
357 totalSizeInframe = bufferTotalFrameSize_;
358 spanSizeInframe = eachReadFrameSize_;
359 byteSizePerFrame = PcmFormatToBit(attr_.format) * attr_.channel / PCM_8_BIT;
360 syncInfoSize = syncInfoSize_;
361 return SUCCESS;
362 }
363
GetMmapHandlePosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)364 int32_t RemoteFastAudioCaptureSource::GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
365 {
366 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
367
368 struct AudioTimeStamp stamp = {};
369 int32_t ret = audioCapture_->GetMmapPosition(frames, stamp);
370 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "get mmap position fail, ret: %{public}d", ret);
371 int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it
372 CHECK_AND_RETURN_RET_LOG(stamp.tvSec >= 0 && stamp.tvSec <= maxSec && stamp.tvNSec >= 0 &&
373 stamp.tvNSec <= SECOND_TO_NANOSECOND, ERR_OPERATION_FAILED,
374 "get invaild time, second: %{public}" PRId64 ", nanosecond: %{public}" PRId64, stamp.tvSec, stamp.tvNSec);
375 timeSec = stamp.tvSec;
376 timeNanoSec = stamp.tvNSec;
377 return ret;
378 }
379
PcmFormatToBit(enum AudioSampleFormat format)380 uint32_t RemoteFastAudioCaptureSource::PcmFormatToBit(enum AudioSampleFormat format)
381 {
382 switch (format) {
383 case SAMPLE_U8:
384 return PCM_8_BIT;
385 case SAMPLE_S16LE:
386 return PCM_16_BIT;
387 case SAMPLE_S24LE:
388 return PCM_24_BIT;
389 case SAMPLE_S32LE:
390 return PCM_32_BIT;
391 case SAMPLE_F32LE:
392 return PCM_32_BIT;
393 default:
394 AUDIO_DEBUG_LOG("unknown format type, set it to default");
395 return PCM_16_BIT;
396 }
397 }
398
ConvertToHdiFormat(AudioSampleFormat format)399 AudioFormat RemoteFastAudioCaptureSource::ConvertToHdiFormat(AudioSampleFormat format)
400 {
401 AudioFormat hdiFormat;
402 switch (format) {
403 case SAMPLE_U8:
404 hdiFormat = AudioFormat::AUDIO_FORMAT_TYPE_PCM_8_BIT;
405 break;
406 case SAMPLE_S16LE:
407 hdiFormat = AudioFormat::AUDIO_FORMAT_TYPE_PCM_16_BIT;
408 break;
409 case SAMPLE_S24LE:
410 hdiFormat = AudioFormat::AUDIO_FORMAT_TYPE_PCM_24_BIT;
411 break;
412 case SAMPLE_S32LE:
413 hdiFormat = AudioFormat::AUDIO_FORMAT_TYPE_PCM_32_BIT;
414 break;
415 default:
416 hdiFormat = AudioFormat::AUDIO_FORMAT_TYPE_PCM_16_BIT;
417 break;
418 }
419
420 return hdiFormat;
421 }
422
GetAudioCategory(AudioScene audioScene)423 AudioCategory RemoteFastAudioCaptureSource::GetAudioCategory(AudioScene audioScene)
424 {
425 AudioCategory audioCategory;
426 switch (audioScene) {
427 case AUDIO_SCENE_DEFAULT:
428 audioCategory = AUDIO_IN_MEDIA;
429 break;
430 case AUDIO_SCENE_RINGING:
431 case AUDIO_SCENE_VOICE_RINGING:
432 audioCategory = AUDIO_IN_RINGTONE;
433 break;
434 case AUDIO_SCENE_PHONE_CALL:
435 audioCategory = AUDIO_IN_CALL;
436 break;
437 case AUDIO_SCENE_PHONE_CHAT:
438 audioCategory = AUDIO_IN_COMMUNICATION;
439 break;
440 default:
441 audioCategory = AUDIO_IN_MEDIA;
442 break;
443 }
444 AUDIO_DEBUG_LOG("audioCategory: %{public}d", audioCategory);
445
446 return audioCategory;
447 }
448
InitAudioSampleAttr(struct AudioSampleAttributes & param)449 void RemoteFastAudioCaptureSource::InitAudioSampleAttr(struct AudioSampleAttributes ¶m)
450 {
451 param.interleaved = CAPTURE_INTERLEAVED;
452 param.format = ConvertToHdiFormat(attr_.format);
453 param.sampleRate = attr_.sampleRate;
454 param.channelCount = attr_.channel;
455 param.period = DEEP_BUFFER_CAPTURE_PERIOD_SIZE;
456 param.frameSize = param.format * param.channelCount;
457 param.isBigEndian = attr_.isBigEndian;
458 param.isSignedData = true;
459 if (param.frameSize != 0) {
460 param.startThreshold = DEEP_BUFFER_CAPTURE_PERIOD_SIZE / (param.frameSize);
461 }
462 param.stopThreshold = INT_MAX;
463 param.silenceThreshold = attr_.bufferSize;
464 param.streamId = static_cast<int32_t>(GenerateUniqueID(AUDIO_HDI_CAPTURE_ID_BASE, HDI_CAPTURE_OFFSET_REMOTE_FAST));
465
466 param.type = attr_.audioStreamFlag == AUDIO_FLAG_VOIP_FAST ? AudioCategory::AUDIO_MMAP_VOIP :
467 AudioCategory::AUDIO_MMAP_NOIRQ;
468 }
469
InitDeviceDesc(struct AudioDeviceDescriptor & deviceDesc)470 void RemoteFastAudioCaptureSource::InitDeviceDesc(struct AudioDeviceDescriptor &deviceDesc)
471 {
472 deviceDesc.pins = AudioPortPin::PIN_IN_MIC;
473 deviceDesc.desc = "";
474 }
475
InitSceneDesc(struct AudioSceneDescriptor & sceneDesc,AudioScene audioScene)476 void RemoteFastAudioCaptureSource::InitSceneDesc(struct AudioSceneDescriptor &sceneDesc, AudioScene audioScene)
477 {
478 sceneDesc.scene.id = GetAudioCategory(audioScene);
479 sceneDesc.desc.pins = AudioPortPin::PIN_IN_MIC;
480 }
481
CreateCapture(void)482 int32_t RemoteFastAudioCaptureSource::CreateCapture(void)
483 {
484 struct AudioSampleAttributes param;
485 struct AudioDeviceDescriptor deviceDesc;
486 InitAudioSampleAttr(param);
487 InitDeviceDesc(deviceDesc);
488
489 AUDIO_INFO_LOG("create capture, format: %{public}u", param.format);
490 HdiAdapterManager &manager = HdiAdapterManager::GetInstance();
491 std::shared_ptr<IDeviceManager> deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_REMOTE);
492 CHECK_AND_RETURN_RET(deviceManager != nullptr, ERR_INVALID_HANDLE);
493
494 void *capture = deviceManager->CreateCapture(deviceNetworkId_, ¶m, &deviceDesc, hdiCaptureId_);
495 audioCapture_.ForceSetRefPtr(static_cast<IAudioCapture *>(capture));
496 CHECK_AND_RETURN_RET(audioCapture_ != nullptr, ERR_NOT_STARTED);
497 deviceManager->RegistCaptureSourceCallback(deviceNetworkId_, hdiCaptureId_, this);
498 if (param.type == AudioCategory::AUDIO_MMAP_NOIRQ || param.type == AudioCategory::AUDIO_MMAP_VOIP) {
499 PrepareMmapBuffer(param);
500 }
501 AUDIO_INFO_LOG("end");
502 return SUCCESS;
503 }
504
PrepareMmapBuffer(const AudioSampleAttributes & param)505 int32_t RemoteFastAudioCaptureSource::PrepareMmapBuffer(const AudioSampleAttributes ¶m)
506 {
507 int32_t totalBufferInMs = 40; // 40: 5 * (6 + 2 * (1)) = 40ms, the buffer size, not latency
508 int32_t reqBufferFrameSize = totalBufferInMs * static_cast<int32_t>(attr_.sampleRate / SECOND_TO_MILLISECOND);
509 struct AudioMmapBufferDescriptor desc;
510
511 CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr");
512 int32_t ret = audioCapture_->ReqMmapBuffer(reqBufferFrameSize, desc);
513 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "request mmap buffer fail, ret:%{public}d", ret);
514 AUDIO_DEBUG_LOG("memoryFd: [%{public}d], totalBufferFrames: [%{public}d], transferFrameSize: [%{public}d], "
515 "isShareable: [%{public}d], offset: [%{public}d]", desc.memoryFd, desc.totalBufferFrames,
516 desc.transferFrameSize, desc.isShareable, desc.offset);
517
518 bufferFd_ = desc.memoryFd; // fcntl(fd, 1030, 3) after dup?
519 int32_t periodFrameMaxSize = 1920000; // 192khz * 10s
520 CHECK_AND_RETURN_RET_LOG(desc.totalBufferFrames >= 0 && desc.transferFrameSize >= 0 &&
521 desc.transferFrameSize <= periodFrameMaxSize, ERR_OPERATION_FAILED,
522 "invalid value, totalBufferFrames: [%{public}d], transferFrameSize: [%{public}d]", desc.totalBufferFrames,
523 desc.transferFrameSize);
524
525 bufferTotalFrameSize_ = static_cast<uint32_t>(desc.totalBufferFrames);
526 eachReadFrameSize_ = static_cast<uint32_t>(desc.transferFrameSize);
527
528 #ifdef DEBUG_DIRECT_USE_HDI
529 bufferSize_ = bufferTotalFrameSize_ * param.channelCount * param.format;
530 ashmemSource_ = new Ashmem(bufferFd_, bufferSize_);
531 AUDIO_DEBUG_LOG("create ashmem source succ, ashmemLen: %{public}zu", bufferSize_);
532 bool tmp = ashmemSource_->MapReadAndWriteAshmem();
533 CHECK_AND_RETURN_RET_LOG(tmp, ERR_OPERATION_FAILED, "map ashmem source fail");
534 #endif
535 return SUCCESS;
536 }
537
CheckPositionTime(void)538 int32_t RemoteFastAudioCaptureSource::CheckPositionTime(void)
539 {
540 int32_t tryCount = MAX_GET_POSITION_TRY_COUNT;
541 uint64_t frames = 0;
542 int64_t timeSec = 0;
543 int64_t timeNanoSec = 0;
544 while (tryCount-- > 0) {
545 ClockTime::RelativeSleep(MAX_GET_POSITION_WAIT_TIME);
546 int32_t ret = GetMmapHandlePosition(frames, timeSec, timeNanoSec);
547 int64_t curTime = ClockTime::GetCurNano();
548 int64_t curSec = curTime / AUDIO_NS_PER_SECOND;
549 int64_t curNanoSec = curTime - curSec * AUDIO_NS_PER_SECOND;
550 if (ret != SUCCESS || curSec != timeSec || curNanoSec - timeNanoSec > MAX_GET_POSITION_HANDLE_TIME) {
551 AUDIO_WARNING_LOG("tryCount: %{public}d, ret: %{public}d", tryCount, ret);
552 continue;
553 } else {
554 AUDIO_INFO_LOG("check succ");
555 return SUCCESS;
556 }
557 }
558 return ERR_OPERATION_FAILED;
559 }
560
SetDmDeviceType(uint16_t dmDeviceType,DeviceType deviceType)561 void RemoteFastAudioCaptureSource::SetDmDeviceType(uint16_t dmDeviceType, DeviceType deviceType)
562 {
563 AUDIO_INFO_LOG("not support");
564 }
565
566 } // namespace AudioStandard
567 } // namespace OHOS
568