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, ×tamp);
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