• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "remote_fast_audio_capturer_source.h"
17 
18 #include <cinttypes>
19 #include <dlfcn.h>
20 #include <sstream>
21 #include "securec.h"
22 
23 #include "audio_errors.h"
24 #include "audio_log.h"
25 #include "audio_utils.h"
26 
27 namespace OHOS {
28 namespace AudioStandard {
29 std::map<std::string, RemoteFastAudioCapturerSource *> RemoteFastAudioCapturerSource::allRFSources_;
GetInstance(const std::string & deviceNetworkId)30 IMmapAudioCapturerSource *RemoteFastAudioCapturerSource::GetInstance(const std::string& deviceNetworkId)
31 {
32     RemoteFastAudioCapturerSource *rfCapturer = nullptr;
33     // check if it is in our map
34     if (allRFSources_.count(deviceNetworkId)) {
35         return allRFSources_[deviceNetworkId];
36     } else {
37         rfCapturer = new(std::nothrow) RemoteFastAudioCapturerSource(deviceNetworkId);
38         AUDIO_DEBUG_LOG("new Daudio device source: [%{public}s]", deviceNetworkId.c_str());
39         allRFSources_[deviceNetworkId] = rfCapturer;
40     }
41     CHECK_AND_RETURN_RET_LOG((rfCapturer != nullptr), nullptr, "Remote fast audio capturer is null!");
42     return rfCapturer;
43 }
44 
RemoteFastAudioCapturerSource(const std::string & deviceNetworkId)45 RemoteFastAudioCapturerSource::RemoteFastAudioCapturerSource(const std::string& deviceNetworkId)
46     : deviceNetworkId_(deviceNetworkId)
47 {
48     AUDIO_INFO_LOG("RemoteFastAudioCapturerSource Constract.");
49 }
50 
~RemoteFastAudioCapturerSource()51 RemoteFastAudioCapturerSource::~RemoteFastAudioCapturerSource()
52 {
53     if (capturerInited_.load()) {
54         RemoteFastAudioCapturerSource::DeInit();
55     }
56     AUDIO_INFO_LOG("~RemoteFastAudioCapturerSource end.");
57 }
58 
IsInited()59 bool RemoteFastAudioCapturerSource::IsInited()
60 {
61     return capturerInited_.load();
62 }
63 
DeInit()64 void RemoteFastAudioCapturerSource::DeInit()
65 {
66     AUDIO_INFO_LOG("%{public}s enter.", __func__);
67     started_.store(false);
68     capturerInited_.store(false);
69 #ifdef DEBUG_DIRECT_USE_HDI
70     if (pfd_) {
71         fclose(pfd_);
72         pfd_ = nullptr;
73     }
74     if (ashmemSource_ != nullptr) {
75         ashmemSource_->UnmapAshmem();
76         ashmemSource_->CloseAshmem();
77         ashmemSource_ = nullptr;
78         AUDIO_INFO_LOG("%{public}s: Uninit source ashmem OK.", __func__);
79     }
80 #endif // DEBUG_DIRECT_USE_HDI
81     if (bufferFd_ != INVALID_FD) {
82         close(bufferFd_);
83         bufferFd_ = INVALID_FD;
84     }
85     if ((audioCapture_ != nullptr) && (audioAdapter_ != nullptr)) {
86         audioAdapter_->DestroyCapture(audioAdapter_, audioCapture_);
87         audioCapture_ = nullptr;
88     }
89 
90     if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
91         if (routeHandle_ != -1) {
92             audioAdapter_->ReleaseAudioRoute(audioAdapter_, routeHandle_);
93         }
94         audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
95     }
96     audioAdapter_ = nullptr;
97     audioManager_ = nullptr;
98     // remove map recorder.
99     RemoteFastAudioCapturerSource *temp = allRFSources_[this->deviceNetworkId_];
100     if (temp != nullptr) {
101         delete temp;
102         temp = nullptr;
103         allRFSources_.erase(this->deviceNetworkId_);
104     }
105 }
106 
Init(IAudioSourceAttr & attr)107 int32_t RemoteFastAudioCapturerSource::Init(IAudioSourceAttr &attr)
108 {
109     AUDIO_INFO_LOG("%{public}s enter.", __func__);
110     attr_ = attr;
111     int32_t ret = InitAudioManager();
112     if (ret != SUCCESS) {
113         AUDIO_ERR_LOG("Init audio manager fail, ret %{public}d.", ret);
114         return ERR_INVALID_HANDLE;
115     }
116 
117     int32_t size = 0;
118     struct AudioAdapterDescriptor *descs = nullptr;
119     ret = audioManager_->GetAllAdapters(audioManager_, &descs, &size);
120     if (size == 0 || descs == nullptr || ret != 0) {
121         AUDIO_ERR_LOG("Get adapters fail, ret %{public}d.", ret);
122         return ERR_INVALID_HANDLE;
123     }
124     AUDIO_INFO_LOG("Get [%{publid}d] adapters", size);
125     int32_t targetIdx = GetTargetAdapterPort(descs, size, attr_.deviceNetworkId);
126     CHECK_AND_RETURN_RET_LOG((targetIdx >= 0), ERR_INVALID_INDEX, "can not find target adapter.");
127 
128     struct AudioAdapterDescriptor *desc = &descs[targetIdx];
129     ret = audioManager_->LoadAdapter(audioManager_, desc, &audioAdapter_);
130     if (ret != 0 || audioAdapter_ == nullptr) {
131         AUDIO_ERR_LOG("Load audio adapter fail, ret %{public}d.", ret);
132         return ERR_INVALID_HANDLE;
133     }
134     ret = audioAdapter_->InitAllPorts(audioAdapter_);
135     if (ret != 0) {
136         AUDIO_ERR_LOG("Init audio adapter ports fail, ret %{public}d.", ret);
137         return ERR_DEVICE_INIT;
138     }
139 
140     if (!isCapturerCreated_.load()) {
141         CHECK_AND_RETURN_RET_LOG(CreateCapture(audioPort_) == SUCCESS, ERR_NOT_STARTED,
142             "Create capture failed, Audio Port: %{public}d.", audioPort_.portId);
143     }
144     capturerInited_.store(true);
145 
146 #ifdef DEBUG_DIRECT_USE_HDI
147     AUDIO_INFO_LOG("Dump audio source attr: [%{public}s]", printRemoteAttr(attr_).c_str());
148     pfd_ = fopen(audioFilePath, "a+"); // here will not create a file if not exit.
149     AUDIO_INFO_LOG("Init dump file [%{public}s]", audioFilePath);
150     if (pfd_ == nullptr) {
151         AUDIO_ERR_LOG("Opening remote pcm file [%{public}s] fail.", audioFilePath);
152     }
153 #endif // DEBUG_DIRECT_USE_HDI
154 
155     AUDIO_INFO_LOG("%{public}s end.", __func__);
156     return SUCCESS;
157 }
158 
InitAudioManager()159 int32_t RemoteFastAudioCapturerSource::InitAudioManager()
160 {
161     AUDIO_INFO_LOG("%{public}s remote fast capturer enter.", __func__);
162 #ifdef __aarch64__
163     char resolvedPath[100] = "/system/lib64/libdaudio_client.z.so";
164 #else
165     char resolvedPath[100] = "/system/lib/libdaudio_client.z.so";
166 #endif
167     struct AudioManager *(*GetAudioManagerFuncs)() = nullptr;
168 
169     void *handle = dlopen(resolvedPath, RTLD_LAZY);
170     if (handle == nullptr) {
171         AUDIO_ERR_LOG("dlopen %{public}s fail.", resolvedPath);
172         return ERR_INVALID_HANDLE;
173     }
174     AUDIO_INFO_LOG("dlopen %{public}s OK.", resolvedPath);
175 
176     dlerror();
177     GetAudioManagerFuncs = reinterpret_cast<struct AudioManager *(*)()>(dlsym(handle, "GetAudioManagerFuncs"));
178     if (dlerror() != nullptr || GetAudioManagerFuncs == nullptr) {
179         AUDIO_ERR_LOG("dlsym GetAudioManagerFuncs fail.");
180         return ERR_INVALID_HANDLE;
181     }
182     AUDIO_INFO_LOG("dlsym GetAudioManagerFuncs OK.");
183     audioManager_ = GetAudioManagerFuncs();
184     CHECK_AND_RETURN_RET_LOG((audioManager_ != nullptr), ERR_INVALID_HANDLE, "Init daudio manager fail!");
185 
186     AUDIO_INFO_LOG("Get daudio manager OK.");
187     return SUCCESS;
188 }
189 
GetTargetAdapterPort(struct AudioAdapterDescriptor * descs,int32_t size,const char * networkId)190 int32_t RemoteFastAudioCapturerSource::GetTargetAdapterPort(struct AudioAdapterDescriptor *descs, int32_t size,
191     const char *networkId)
192 {
193     int32_t targetIdx = INVALID_INDEX;
194     for (int32_t index = 0; index < size; index++) {
195         struct AudioAdapterDescriptor *desc = &descs[index];
196         if (desc == nullptr || desc->adapterName == nullptr) {
197             continue;
198         }
199         targetIdx = index;
200         for (uint32_t port = 0; port < desc->portNum; port++) {
201             // Only find out the port of mic
202             if (desc->ports[port].portId == PIN_IN_MIC) {
203                 audioPort_ = desc->ports[port];
204                 break;
205             }
206         }
207     }
208     return targetIdx;
209 }
210 
CreateCapture(const struct AudioPort & capturePort)211 int32_t RemoteFastAudioCapturerSource::CreateCapture(const struct AudioPort &capturePort)
212 {
213     CHECK_AND_RETURN_RET_LOG((audioAdapter_ != nullptr), ERR_INVALID_HANDLE,
214         "%{public}s: audio adapter is null.", __func__);
215     struct AudioSampleAttributes captureAttr;
216     InitAttrs(captureAttr);
217     struct AudioDeviceDescriptor deviceDesc;
218     deviceDesc.portId = capturePort.portId;
219     deviceDesc.pins = PIN_IN_MIC;
220     deviceDesc.desc = nullptr;
221     int32_t ret = audioAdapter_->CreateCapture(audioAdapter_, &deviceDesc, &captureAttr, &audioCapture_);
222     if (ret != 0 || audioCapture_ == nullptr) {
223         AUDIO_ERR_LOG("%{public}s create capture failed.", __func__);
224         return ERR_NOT_STARTED;
225     }
226     if (captureAttr.type == AUDIO_MMAP_NOIRQ) {
227         InitAshmem(captureAttr); // The remote fast source first start
228     }
229 
230     isCapturerCreated_.store(true);
231     AUDIO_INFO_LOG("%{public}s end, capture format: %{public}d.", __func__, captureAttr.format);
232     return SUCCESS;
233 }
234 
InitAshmem(const struct AudioSampleAttributes & attrs)235 int32_t RemoteFastAudioCapturerSource::InitAshmem(const struct AudioSampleAttributes &attrs)
236 {
237     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
238         "%{public}s: audio capture is null.", __func__);
239 
240     int32_t reqSize = 1440;
241     struct AudioMmapBufferDescriptor desc = {0};
242     int32_t ret = audioCapture_->attr.ReqMmapBuffer(audioCapture_, reqSize, &desc);
243     CHECK_AND_RETURN_RET_LOG((ret == 0), ERR_OPERATION_FAILED,
244         "%{public}s require mmap buffer failed, ret %{public}d.", __func__, ret);
245     AUDIO_INFO_LOG("%{public}s audio capture mmap buffer info, memoryAddress[%{private}p] memoryFd[%{public}d] "
246         "totalBufferFrames [%{public}d] transferFrameSize[%{public}d] isShareable[%{public}d] offset[%{public}d]",
247         __func__, desc.memoryAddress, desc.memoryFd, desc.totalBufferFrames, desc.transferFrameSize,
248         desc.isShareable, desc.offset);
249 
250     bufferFd_ = desc.memoryFd;
251     int32_t periodFrameMaxSize = 1920000; // 192khz * 10s
252     if (desc.totalBufferFrames < 0 || desc.transferFrameSize < 0 || desc.transferFrameSize > periodFrameMaxSize) {
253         AUDIO_ERR_LOG("ReqMmapBuffer invalid values: totalBufferFrames[%{public}d] transferFrameSize[%{public}d]",
254             desc.totalBufferFrames, desc.transferFrameSize);
255         return ERR_OPERATION_FAILED;
256     }
257     bufferTotalFrameSize_ = desc.totalBufferFrames;
258     eachReadFrameSize_ = desc.transferFrameSize;
259 
260 #ifdef DEBUG_DIRECT_USE_HDI
261     ashmemLen_ = desc.totalBufferFrames * attrs.channelCount * attrs.format;
262     ashmemSource_ = new Ashmem(bufferFd_, ashmemLen_);
263     AUDIO_INFO_LOG("%{public}s creat ashmem source OK, ashmemLen %{public}d.", __func__, ashmemLen_);
264     if (!(ashmemSource_->MapReadAndWriteAshmem())) {
265         AUDIO_ERR_LOG("%{public}s map ashmem source failed.", __func__);
266         return ERR_OPERATION_FAILED;
267     }
268     lenPerRead_ = desc.transferFrameSize * attrs.channelCount * attrs.format;
269     AUDIO_INFO_LOG("%{public}s map ashmem source OK, lenPerWrite %{public}d.", __func__, lenPerRead_);
270 #endif
271     return SUCCESS;
272 }
273 
InitAttrs(struct AudioSampleAttributes & attrs)274 void RemoteFastAudioCapturerSource::InitAttrs(struct AudioSampleAttributes &attrs)
275 {
276     /* Initialization of audio parameters for playback */
277     attrs.type = AUDIO_MMAP_NOIRQ;
278     attrs.interleaved = CAPTURE_INTERLEAVED;
279     attrs.format = ConverToHdiFormat(attr_.format);
280     attrs.sampleRate = attr_.sampleRate;
281     attrs.channelCount = attr_.channel;
282     attrs.period = DEEP_BUFFER_CAPTURER_PERIOD_SIZE;
283     attrs.frameSize = attrs.format * attrs.channelCount;
284     attrs.isBigEndian = attr_.isBigEndian;
285     attrs.isSignedData = true;
286     attrs.startThreshold = DEEP_BUFFER_CAPTURER_PERIOD_SIZE / (attrs.frameSize);
287     attrs.stopThreshold = INT_32_MAX;
288     attrs.silenceThreshold = attr_.bufferSize;
289     attrs.streamId = REMOTE_FAST_INPUT_STREAM_ID;
290 }
291 
ConverToHdiFormat(AudioSampleFormat format)292 AudioFormat RemoteFastAudioCapturerSource::ConverToHdiFormat(AudioSampleFormat format)
293 {
294     AudioFormat hdiFormat;
295     switch (format) {
296         case SAMPLE_U8:
297             hdiFormat = AUDIO_FORMAT_TYPE_PCM_8_BIT;
298             break;
299         case SAMPLE_S16LE:
300             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
301             break;
302         case SAMPLE_S24LE:
303             hdiFormat = AUDIO_FORMAT_TYPE_PCM_24_BIT;
304             break;
305         case SAMPLE_S32LE:
306             hdiFormat = AUDIO_FORMAT_TYPE_PCM_32_BIT;
307             break;
308         default:
309             hdiFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
310             break;
311     }
312     return hdiFormat;
313 }
314 
printRemoteAttr(IAudioSourceAttr attr_)315 inline std::string printRemoteAttr(IAudioSourceAttr attr_)
316 {
317     std::stringstream value;
318     value << "adapterName[" << attr_.adapterName << "] openMicSpeaker[" << attr_.open_mic_speaker << "] ";
319     value << "format[" << static_cast<int32_t>(attr_.format) << "] sampleFmt[" << attr_.sampleFmt << "] ";
320     value << "sampleRate[" << attr_.sampleRate << "] channel[" << attr_.channel << "] ";
321     value << "volume[" << attr_.volume << "] filePath[" << attr_.filePath << "] ";
322     value << "deviceNetworkId[" << attr_.deviceNetworkId << "] device_type[" << attr_.deviceType << "]";
323     return value.str();
324 }
325 
Start(void)326 int32_t RemoteFastAudioCapturerSource::Start(void)
327 {
328     AUDIO_INFO_LOG("%{public}s enter.", __func__);
329     if (!isCapturerCreated_.load()) {
330         if (CreateCapture(audioPort_) != SUCCESS) {
331             AUDIO_ERR_LOG("Create capture failed, Audio Port: %{public}d.", audioPort_.portId);
332             return ERR_NOT_STARTED;
333         }
334     }
335 
336     if (started_.load()) {
337         AUDIO_INFO_LOG("Remote fast capturer is already start.");
338         return SUCCESS;
339     }
340 
341     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
342         "%{public}s: audio capture is null.", __func__);
343     int32_t ret = audioCapture_->control.Start(reinterpret_cast<AudioHandle>(audioCapture_));
344     if (ret != 0) {
345         AUDIO_ERR_LOG("Remote fast capturer start fail, ret %{public}d.", ret);
346         return ERR_NOT_STARTED;
347     }
348 
349     ClockTime::RelativeSleep(CAPTURE_FIRST_FRIME_WAIT_NANO);
350     uint64_t curHdiWritePos = 0;
351     int64_t timeSec = 0;
352     int64_t timeNanoSec = 0;
353     int64_t writeTime = 0;
354     while (true) {
355         ret = GetMmapHandlePosition(curHdiWritePos, timeSec, timeNanoSec);
356         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "%{public}s get source handle info fail.", __func__);
357         writeTime = timeNanoSec + timeSec * SECOND_TO_NANOSECOND;
358         if (writeTime > 0) {
359             break;
360         }
361         ClockTime::RelativeSleep(CAPTURE_RESYNC_SLEEP_NANO);
362     }
363     started_.store(true);
364 
365     AUDIO_INFO_LOG("%{public}s OK, curHdiWritePos %{public}" PRIu64", writeTime %{public}" PRId64" ns.",
366         __func__, curHdiWritePos, writeTime);
367     return SUCCESS;
368 }
369 
CaptureFrame(char * frame,uint64_t requestBytes,uint64_t & replyBytes)370 int32_t RemoteFastAudioCapturerSource::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes)
371 {
372     AUDIO_DEBUG_LOG("%{public}s capture frame is not supported.", __func__);
373     return SUCCESS;
374 }
375 
SetVolume(float left,float right)376 int32_t RemoteFastAudioCapturerSource::SetVolume(float left, float right)
377 {
378     AUDIO_INFO_LOG("%{public}s enter, left %{public}f, right %{public}f.", __func__, left, right);
379     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
380         "%{public}s: audio capture is null.", __func__);
381 
382     float volume;
383     leftVolume_ = left;
384     rightVolume_ = right;
385     if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
386         volume = rightVolume_;
387     } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
388         volume = leftVolume_;
389     } else {
390         volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
391     }
392 
393     int32_t ret = audioCapture_->volume.SetVolume(reinterpret_cast<AudioHandle>(audioCapture_), volume);
394     if (ret) {
395         AUDIO_ERR_LOG("Remote fast capturer set volume fail, ret %{public}d.", ret);
396     }
397     return ret;
398 }
399 
GetVolume(float & left,float & right)400 int32_t RemoteFastAudioCapturerSource::GetVolume(float &left, float &right)
401 {
402     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
403         "%{public}s: audio capture is null.", __func__);
404     float val = 0;
405     audioCapture_->volume.GetVolume((AudioHandle)audioCapture_, &val);
406     left = val;
407     right = val;
408     return SUCCESS;
409 }
410 
SetMute(bool isMute)411 int32_t RemoteFastAudioCapturerSource::SetMute(bool isMute)
412 {
413     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
414         "%{public}s: audio capture is null.", __func__);
415     int32_t ret = audioCapture_->volume.SetMute((AudioHandle)audioCapture_, isMute);
416     if (ret != 0) {
417         AUDIO_ERR_LOG("Remote fast capturer set mute fail, ret %{public}d.", ret);
418     }
419 
420     micMuteState_ = isMute;
421     return SUCCESS;
422 }
423 
GetMute(bool & isMute)424 int32_t RemoteFastAudioCapturerSource::GetMute(bool &isMute)
425 {
426     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
427         "%{public}s: audio capture is null.", __func__);
428     bool isHdiMute = false;
429     int32_t ret = audioCapture_->volume.GetMute((AudioHandle)audioCapture_, &isHdiMute);
430     if (ret != 0) {
431         AUDIO_ERR_LOG("Remote fast capturer get mute fail, ret %{public}d.", ret);
432     }
433 
434     isMute = micMuteState_;
435     return SUCCESS;
436 }
437 
GetTransactionId()438 uint64_t RemoteFastAudioCapturerSource::GetTransactionId()
439 {
440     AUDIO_INFO_LOG("%{public}s enter.", __func__);
441     return reinterpret_cast<uint64_t>(audioCapture_);
442 }
443 
RegisterWakeupCloseCallback(IAudioSourceCallback * callback)444 void RemoteFastAudioCapturerSource::RegisterWakeupCloseCallback(IAudioSourceCallback* callback)
445 {
446     AUDIO_ERR_LOG("RegisterWakeupCloseCallback FAILED");
447 }
448 
RegisterAudioCapturerSourceCallback(IAudioSourceCallback * callback)449 void RemoteFastAudioCapturerSource::RegisterAudioCapturerSourceCallback(IAudioSourceCallback* callback)
450 {
451     AUDIO_ERR_LOG("RegisterAudioCapturerSourceCallback FAILED");
452 }
453 
SetInputPortPin(DeviceType inputDevice,AudioRouteNode & source)454 int32_t RemoteFastAudioCapturerSource::SetInputPortPin(DeviceType inputDevice, AudioRouteNode &source)
455 {
456     int32_t ret = SUCCESS;
457     switch (inputDevice) {
458         case DEVICE_TYPE_MIC:
459             source.ext.device.type = PIN_IN_MIC;
460             source.ext.device.desc = "pin_in_mic";
461             break;
462         case DEVICE_TYPE_WIRED_HEADSET:
463             source.ext.device.type = PIN_IN_HS_MIC;
464             source.ext.device.desc = "pin_in_hs_mic";
465             break;
466         case DEVICE_TYPE_USB_HEADSET:
467             source.ext.device.type = PIN_IN_USB_EXT;
468             source.ext.device.desc = "pin_in_usb_ext";
469             break;
470         default:
471             ret = ERR_NOT_SUPPORTED;
472             break;
473     }
474     return ret;
475 }
476 
SetInputRoute(DeviceType inputDevice)477 int32_t RemoteFastAudioCapturerSource::SetInputRoute(DeviceType inputDevice)
478 {
479     AudioRouteNode source = {};
480     AudioRouteNode sink = {};
481     int32_t ret = SetInputPortPin(inputDevice, source);
482     if (ret != SUCCESS) {
483         AUDIO_ERR_LOG("%{public}s set input port pin fail, ret %{public}d.", __func__, ret);
484         return ret;
485     }
486 
487     source.portId = audioPort_.portId;
488     source.role = AUDIO_PORT_SOURCE_ROLE;
489     source.type = AUDIO_PORT_DEVICE_TYPE;
490     source.ext.device.moduleId = 0;
491 
492     sink.portId = 0;
493     sink.role = AUDIO_PORT_SINK_ROLE;
494     sink.type = AUDIO_PORT_MIX_TYPE;
495     sink.ext.mix.moduleId = 0;
496     sink.ext.mix.streamId = REMOTE_FAST_INPUT_STREAM_ID;
497 
498     AudioRoute route = {
499         .sourcesNum = 1,
500         .sources = &source,
501         .sinksNum = 1,
502         .sinks = &sink,
503     };
504 
505     CHECK_AND_RETURN_RET_LOG((audioAdapter_ != nullptr), ERR_INVALID_HANDLE,
506         "%{public}s: audio adapter is null.", __func__);
507     ret = audioAdapter_->UpdateAudioRoute(audioAdapter_, &route, &routeHandle_);
508     AUDIO_DEBUG_LOG("AudioCapturerSource: UpdateAudioRoute returns: %{public}d", ret);
509     if (ret != 0) {
510         AUDIO_ERR_LOG("AudioCapturerSource: UpdateAudioRoute failed");
511         return ERR_OPERATION_FAILED;
512     }
513     return SUCCESS;
514 }
515 
GetAudioCategory(AudioScene audioScene)516 AudioCategory RemoteFastAudioCapturerSource::GetAudioCategory(AudioScene audioScene)
517 {
518     AudioCategory audioCategory;
519     switch (audioScene) {
520         case AUDIO_SCENE_DEFAULT:
521             audioCategory = AUDIO_IN_MEDIA;
522             break;
523         case AUDIO_SCENE_RINGING:
524             audioCategory = AUDIO_IN_RINGTONE;
525             break;
526         case AUDIO_SCENE_PHONE_CALL:
527             audioCategory = AUDIO_IN_CALL;
528             break;
529         case AUDIO_SCENE_PHONE_CHAT:
530             audioCategory = AUDIO_IN_COMMUNICATION;
531             break;
532         default:
533             audioCategory = AUDIO_IN_MEDIA;
534             break;
535     }
536     AUDIO_DEBUG_LOG("RemoteFastAudioCapturerSource: Audio category returned is: %{public}d", audioCategory);
537 
538     return audioCategory;
539 }
540 
SetAudioScene(AudioScene audioScene,DeviceType activeDevice)541 int32_t RemoteFastAudioCapturerSource::SetAudioScene(AudioScene audioScene, DeviceType activeDevice)
542 {
543     AUDIO_INFO_LOG("%{public}s enter: scene: %{public}d, device %{public}d.", __func__,
544         audioScene, activeDevice);
545     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
546         "%{public}s: audio capture is null.", __func__);
547     struct AudioSceneDescriptor scene;
548     scene.scene.id = GetAudioCategory(audioScene);
549     scene.desc.pins = PIN_IN_MIC;
550     if (audioCapture_->scene.SelectScene == nullptr) {
551         AUDIO_ERR_LOG("AudioCapturerSource: Select scene nullptr");
552         return ERR_OPERATION_FAILED;
553     }
554 
555     AUDIO_INFO_LOG("AudioCapturerSource::SelectScene start");
556     int32_t ret = audioCapture_->scene.SelectScene((AudioHandle)audioCapture_, &scene);
557     AUDIO_INFO_LOG("AudioCapturerSource::SelectScene over");
558     if (ret < 0) {
559         AUDIO_ERR_LOG("AudioCapturerSource: Select scene FAILED: %{public}d", ret);
560         return ERR_OPERATION_FAILED;
561     }
562     AUDIO_INFO_LOG("AudioCapturerSource::Select audio scene SUCCESS: %{public}d", audioScene);
563     return SUCCESS;
564 }
565 
PcmFormatToBits(AudioSampleFormat format)566 uint32_t RemoteFastAudioCapturerSource::PcmFormatToBits(AudioSampleFormat format)
567 {
568     switch (format) {
569         case SAMPLE_U8:
570             return PCM_8_BIT;
571         case SAMPLE_S16LE:
572             return PCM_16_BIT;
573         case SAMPLE_S24LE:
574             return PCM_24_BIT;
575         case SAMPLE_S32LE:
576             return PCM_32_BIT;
577         case SAMPLE_F32LE:
578             return PCM_32_BIT;
579         default:
580             return PCM_24_BIT;
581     }
582 }
583 
GetMmapBufferInfo(int & fd,uint32_t & totalSizeInframe,uint32_t & spanSizeInframe,uint32_t & byteSizePerFrame)584 int32_t RemoteFastAudioCapturerSource::GetMmapBufferInfo(int &fd, uint32_t &totalSizeInframe,
585     uint32_t &spanSizeInframe, uint32_t &byteSizePerFrame)
586 {
587     if (bufferFd_ == INVALID_FD) {
588         AUDIO_ERR_LOG("buffer fd has been released!");
589         return ERR_INVALID_HANDLE;
590     }
591     fd = bufferFd_;
592     totalSizeInframe = bufferTotalFrameSize_;
593     spanSizeInframe = eachReadFrameSize_;
594     byteSizePerFrame = PcmFormatToBits(attr_.format) * attr_.channel / PCM_8_BIT;
595     return SUCCESS;
596 }
597 
GetMmapHandlePosition(uint64_t & frames,int64_t & timeSec,int64_t & timeNanoSec)598 int32_t RemoteFastAudioCapturerSource::GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec)
599 {
600     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
601         "%{public}s: audio capture is null.", __func__);
602 
603     struct AudioTimeStamp timestamp = {};
604     int32_t ret = audioCapture_->attr.GetMmapPosition((AudioHandle)audioCapture_, &frames, &timestamp);
605     if (ret != 0) {
606         AUDIO_ERR_LOG("Hdi GetMmapPosition filed, ret:%{public}d!", ret);
607         return ERR_OPERATION_FAILED;
608     }
609 
610     int64_t maxSec = 9223372036; // (9223372036 + 1) * 10^9 > INT64_MAX, seconds should not bigger than it.
611     if (timestamp.tvSec < 0 || timestamp.tvSec > maxSec || timestamp.tvNSec < 0 ||
612         timestamp.tvNSec > SECOND_TO_NANOSECOND) {
613         AUDIO_ERR_LOG("Hdi GetMmapPosition get invaild second:%{public}" PRId64 " or nanosecond:%{public}" PRId64 " !",
614             timestamp.tvSec, timestamp.tvNSec);
615         return ERR_OPERATION_FAILED;
616     }
617     timeSec = timestamp.tvSec;
618     timeNanoSec = timestamp.tvNSec;
619 
620     return SUCCESS;
621 }
622 
Stop(void)623 int32_t RemoteFastAudioCapturerSource::Stop(void)
624 {
625     AUDIO_INFO_LOG("%{public}s enter.", __func__);
626     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
627         "%{public}s: audio capture is null.", __func__);
628 
629     if (started_.load()) {
630         int32_t ret = audioCapture_->control.Stop(reinterpret_cast<AudioHandle>(audioCapture_));
631         if (ret != 0) {
632             AUDIO_ERR_LOG("Remote fast capturer stop fail, ret %{public}d.", ret);
633             return ERR_OPERATION_FAILED;
634         }
635         started_.store(false);
636     }
637     return SUCCESS;
638 }
639 
Pause(void)640 int32_t RemoteFastAudioCapturerSource::Pause(void)
641 {
642     AUDIO_INFO_LOG("%{public}s enter.", __func__);
643     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
644         "%{public}s: audio capture is null.", __func__);
645 
646     if (!started_.load()) {
647         AUDIO_ERR_LOG("%{public}s: Invalid start state %{public}d.", __func__, started_.load());
648         return ERR_OPERATION_FAILED;
649     }
650 
651     if (!paused_.load()) {
652         int32_t ret = audioCapture_->control.Pause(reinterpret_cast<AudioHandle>(audioCapture_));
653         if (ret != 0) {
654             AUDIO_ERR_LOG("Remote fast capturer pause fail, ret %{public}d.", ret);
655             return ERR_OPERATION_FAILED;
656         }
657         paused_.store(true);
658     }
659     return SUCCESS;
660 }
661 
Resume(void)662 int32_t RemoteFastAudioCapturerSource::Resume(void)
663 {
664     AUDIO_INFO_LOG("%{public}s enter.", __func__);
665     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
666         "%{public}s: audio capture is null.", __func__);
667 
668     if (!started_.load()) {
669         AUDIO_ERR_LOG("%{public}s: Invalid start state %{public}d.", __func__, started_.load());
670         return ERR_OPERATION_FAILED;
671     }
672 
673     if (paused_.load()) {
674         int32_t ret = audioCapture_->control.Resume(reinterpret_cast<AudioHandle>(audioCapture_));
675         if (ret != 0) {
676             AUDIO_ERR_LOG("Remote fast capturer resume fail, ret %{public}d.", ret);
677             return ERR_OPERATION_FAILED;
678         }
679         paused_.store(false);
680     }
681     return SUCCESS;
682 }
683 
Reset(void)684 int32_t RemoteFastAudioCapturerSource::Reset(void)
685 {
686     AUDIO_INFO_LOG("%{public}s enter.", __func__);
687     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
688         "%{public}s: audio capture is null.", __func__);
689     if (!started_.load()) {
690         AUDIO_ERR_LOG("%{public}s: Invalid start state %{public}d.", __func__, started_.load());
691         return ERR_OPERATION_FAILED;
692     }
693 
694     int32_t ret = audioCapture_->control.Flush(reinterpret_cast<AudioHandle>(audioCapture_));
695     if (ret != 0) {
696         AUDIO_ERR_LOG("Remote fast capturer reset fail, ret %{public}d.", ret);
697         return ERR_OPERATION_FAILED;
698     }
699     return SUCCESS;
700 }
701 
Flush(void)702 int32_t RemoteFastAudioCapturerSource::Flush(void)
703 {
704     AUDIO_INFO_LOG("%{public}s enter.", __func__);
705     CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE,
706         "%{public}s: audio capture is null.", __func__);
707     if (!started_.load()) {
708         AUDIO_ERR_LOG("%{public}s: Invalid start state %{public}d.", __func__, started_.load());
709         return ERR_OPERATION_FAILED;
710     }
711 
712     int32_t ret = audioCapture_->control.Flush(reinterpret_cast<AudioHandle>(audioCapture_));
713     if (ret != 0) {
714         AUDIO_ERR_LOG("Remote fast capturer flush fail, ret %{public}d.", ret);
715         return ERR_OPERATION_FAILED;
716     }
717     return SUCCESS;
718 }
719 } // namespace AudioStandard
720 } // namesapce OHOS
721