1 /*
2 * Copyright (c) 2022 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 <cstring>
17 #include <dlfcn.h>
18 #include <string>
19
20 #include "audio_errors.h"
21 #include "audio_log.h"
22 #include "remote_audio_capturer_source.h"
23
24 using namespace std;
25
26 namespace OHOS {
27 namespace AudioStandard {
28 #ifdef DEBUG_CAPTURE_DUMP
29 const char *g_audioOutTestFilePath = "/data/local/tmp/remote_audio_capture.pcm";
30 #endif // DEBUG_CAPTURE_DUMP
31
32 std::map<std::string, RemoteAudioCapturerSource *> RemoteAudioCapturerSource::allRemoteSources;
GetInstance(std::string deviceNetworkId)33 RemoteAudioCapturerSource *RemoteAudioCapturerSource::GetInstance(std::string deviceNetworkId)
34 {
35 RemoteAudioCapturerSource *audioCapturer_ = nullptr;
36 // check if it is in our map
37 if (allRemoteSources.count(deviceNetworkId)) {
38 return allRemoteSources[deviceNetworkId];
39 } else {
40 audioCapturer_ = new(std::nothrow) RemoteAudioCapturerSource(deviceNetworkId);
41 AUDIO_DEBUG_LOG("new Daudio device source:[%{public}s]", deviceNetworkId.c_str());
42 allRemoteSources[deviceNetworkId] = audioCapturer_;
43 }
44 CHECK_AND_RETURN_RET_LOG((audioCapturer_ != nullptr), nullptr, "null audioCapturer!");
45 return audioCapturer_;
46 }
47
RemoteAudioCapturerSource(std::string deviceNetworkId)48 RemoteAudioCapturerSource::RemoteAudioCapturerSource(std::string deviceNetworkId)
49 {
50 this->deviceNetworkId_ = deviceNetworkId;
51 capturerInited_ = false;
52 audioManager_ = nullptr;
53 audioAdapter_ = nullptr;
54 audioCapture_ = nullptr;
55 }
56
~RemoteAudioCapturerSource()57 RemoteAudioCapturerSource::~RemoteAudioCapturerSource()
58 {
59 if (capturerInited_ == true) {
60 DeInit();
61 } else {
62 AUDIO_INFO_LOG("RemoteAudioCapturerSource has already DeInit.");
63 }
64 }
65
DeInit()66 void RemoteAudioCapturerSource::DeInit()
67 {
68 capturerInited_ = false;
69
70 if ((audioCapture_ != nullptr) && (audioAdapter_ != nullptr)) {
71 audioAdapter_->DestroyCapture(audioAdapter_, audioCapture_);
72 }
73 audioCapture_ = nullptr;
74
75 if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
76 if (routeHandle_ != -1) {
77 audioAdapter_->ReleaseAudioRoute(audioAdapter_, routeHandle_);
78 }
79 audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
80 }
81 audioAdapter_ = nullptr;
82 audioManager_ = nullptr;
83
84 // remove map recorder.
85 RemoteAudioCapturerSource *temp = allRemoteSources[this->deviceNetworkId_];
86 if (temp != nullptr) {
87 delete temp;
88 temp = nullptr;
89 allRemoteSources.erase(this->deviceNetworkId_);
90 }
91 #ifdef DEBUG_CAPTURE_DUMP
92 if (pfd != nullptr) {
93 fclose(pfd);
94 pfd = nullptr;
95 }
96 #endif // DEBUG_CAPTURE_DUMP
97 }
98
SwitchAdapterCapture(struct AudioAdapterDescriptor * descs,int32_t size,const std::string & adapterNameCase,struct AudioPort & capturePort)99 int32_t SwitchAdapterCapture(struct AudioAdapterDescriptor *descs, int32_t size, const std::string &adapterNameCase,
100 struct AudioPort &capturePort)
101 {
102 if (descs == nullptr) {
103 return ERROR;
104 }
105
106 for (int32_t index = 0; index < size; index++) {
107 struct AudioAdapterDescriptor *desc = &descs[index];
108 if (desc == nullptr) {
109 continue;
110 }
111 if (adapterNameCase.compare(desc->adapterName) != 0) {
112 continue;
113 }
114 for (uint32_t port = 0; port < desc->portNum; port++) {
115 // Only find out the port of in in the sound card
116 if (desc->ports[port].portId == PIN_IN_MIC) {
117 capturePort = desc->ports[port];
118 return index;
119 }
120 }
121 }
122 AUDIO_ERR_LOG("SwitchAdapterCapture Fail");
123
124 return ERR_INVALID_INDEX;
125 }
126
CreateCapture(struct AudioPort & capturePort)127 int32_t RemoteAudioCapturerSource::CreateCapture(struct AudioPort &capturePort)
128 {
129 int32_t ret;
130 struct AudioSampleAttributes param;
131 param.type = AUDIO_IN_MEDIA;
132 param.period = deepBufferCapturePeriodSize;
133 param.streamId = internalInputStreamId;
134 param.isSignedData = true;
135 param.stopThreshold = maxInt32;
136 param.silenceThreshold = audioBufferSize;
137 // User needs to set
138 param.sampleRate = attr_.sampleRate;
139 param.format = attr_.format;
140 param.isBigEndian = attr_.isBigEndian;
141 param.channelCount = attr_.channel;
142 param.silenceThreshold = attr_.bufferSize;
143 param.frameSize = param.format * param.channelCount;
144 param.startThreshold = deepBufferCapturePeriodSize / (param.frameSize);
145
146 struct AudioDeviceDescriptor deviceDesc;
147 deviceDesc.portId = capturePort.portId;
148 deviceDesc.pins = PIN_IN_MIC;
149 deviceDesc.desc = nullptr;
150
151 ret = audioAdapter_->CreateCapture(audioAdapter_, &deviceDesc, ¶m, &audioCapture_);
152 if (audioCapture_ == nullptr || ret < 0) {
153 AUDIO_ERR_LOG("Create capture failed");
154 return ERR_NOT_STARTED;
155 }
156
157 return SUCCESS;
158 }
159
Init(IAudioSourceAttr & attr)160 int32_t RemoteAudioCapturerSource::Init(IAudioSourceAttr &attr)
161 {
162 attr_ = attr;
163 int32_t ret;
164 int32_t index;
165 int32_t size = 0;
166 struct AudioAdapterDescriptor *descs = nullptr;
167 if (InitAudioManager() != 0) {
168 AUDIO_ERR_LOG("Init audio manager Fail");
169 return ERR_INVALID_HANDLE;
170 }
171 ret = audioManager_->GetAllAdapters(audioManager_, &descs, &size);
172 // adapters is 0~3
173 if (size == 0 || descs == nullptr || ret != 0) {
174 AUDIO_ERR_LOG("Get adapters Fail");
175 return ERR_NOT_STARTED;
176 }
177 // Get qualified sound card and port
178 std::string adapterNameCase = attr_.deviceNetworkId;
179 index = SwitchAdapterCapture(descs, size, adapterNameCase, audioPort);
180 if (index < 0) {
181 AUDIO_ERR_LOG("Switch Adapter Capture Fail");
182 return ERR_NOT_STARTED;
183 }
184 struct AudioAdapterDescriptor *desc = &descs[index];
185 if (audioManager_->LoadAdapter(audioManager_, desc, &audioAdapter_) != 0) {
186 AUDIO_ERR_LOG("Load Adapter Fail");
187 return ERR_NOT_STARTED;
188 }
189 if (audioAdapter_ == nullptr) {
190 AUDIO_ERR_LOG("Load audio device failed");
191 return ERR_NOT_STARTED;
192 }
193
194 // Inittialization port information, can fill through mode and other parameters
195 ret = audioAdapter_->InitAllPorts(audioAdapter_);
196 if (ret != 0) {
197 AUDIO_ERR_LOG("InitAllPorts failed");
198 return ERR_DEVICE_INIT;
199 }
200 if (CreateCapture(audioPort) != 0) {
201 AUDIO_ERR_LOG("Create capture failed");
202 return ERR_NOT_STARTED;
203 }
204 capturerInited_ = true;
205
206 #ifdef DEBUG_CAPTURE_DUMP
207 pfd = fopen(g_audioOutTestFilePath, "rb");
208 if (pfd == nullptr) {
209 AUDIO_ERR_LOG("Error opening pcm test file!");
210 }
211 #endif // DEBUG_CAPTURE_DUMP
212
213 return SUCCESS;
214 }
215
IsInited(void)216 bool RemoteAudioCapturerSource::IsInited(void)
217 {
218 return capturerInited_;
219 }
220
InitAudioManager()221 int32_t RemoteAudioCapturerSource::InitAudioManager()
222 {
223 AUDIO_INFO_LOG("RemoteAudioCapturerSource: Initialize audio proxy manager");
224 #ifdef PRODUCT_M40
225 #ifdef __aarch64__
226 char resolvedPath[100] = "/vendor/lib64/libdaudio_client.z.so";
227 #else
228 char resolvedPath[100] = "/vendor/lib/libdaudio_client.z.so";
229 #endif
230 struct AudioManager *(*GetAudioManagerFuncs)() = nullptr;
231
232 void *handle_ = dlopen(resolvedPath, 1);
233 if (handle_ == nullptr) {
234 AUDIO_ERR_LOG("Open so Fail");
235 return ERR_INVALID_HANDLE;
236 }
237 AUDIO_INFO_LOG("dlopen successful");
238
239 GetAudioManagerFuncs = (struct AudioManager *(*)())(dlsym(handle_, "GetAudioManagerFuncs"));
240 if (GetAudioManagerFuncs == nullptr) {
241 return ERR_INVALID_HANDLE;
242 }
243 AUDIO_INFO_LOG("GetAudioManagerFuncs done");
244
245 audioManager_ = GetAudioManagerFuncs();
246 if (audioManager_ == nullptr) {
247 return ERR_INVALID_HANDLE;
248 }
249 AUDIO_INFO_LOG("daudio manager created");
250 #else
251 audioManager_ = GetAudioManagerFuncs();
252 #endif // PRODUCT_M40
253 CHECK_AND_RETURN_RET_LOG((audioManager_ != nullptr), ERR_INVALID_HANDLE, "Initialize audio proxy failed!");
254
255 return SUCCESS;
256 }
257
CaptureFrame(char * frame,uint64_t requestBytes,uint64_t & replyBytes)258 int32_t RemoteAudioCapturerSource::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes)
259 {
260 int32_t ret;
261 CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!");
262
263 ret = audioCapture_->CaptureFrame(audioCapture_, frame, requestBytes, &replyBytes);
264 if (ret < 0) {
265 AUDIO_ERR_LOG("Capture Frame Fail");
266 return ERR_READ_FAILED;
267 }
268
269 #ifdef DEBUG_CAPTURE_DUMP
270 if (feof(pfd)) {
271 AUDIO_INFO_LOG("End of the file reached, start reading from beginning");
272 rewind(pfd);
273 }
274 size_t writeResult = fread(frame, 1, requestBytes, pfd);
275 if (writeResult != requestBytes) {
276 AUDIO_ERR_LOG("Failed to read the file.");
277 }
278 #endif // DEBUG_CAPTURE_DUMP
279
280 return SUCCESS;
281 }
282
Start(void)283 int32_t RemoteAudioCapturerSource::Start(void)
284 {
285 AUDIO_INFO_LOG("RemoteAudioCapturerSource::Start in");
286 int32_t ret;
287 CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!");
288 if (!started_) {
289 ret = audioCapture_->control.Start((AudioHandle)audioCapture_);
290 if (ret < 0) {
291 return ERR_NOT_STARTED;
292 }
293 started_ = true;
294 }
295 started_ = true;
296 return SUCCESS;
297 }
298
SetVolume(float left,float right)299 int32_t RemoteAudioCapturerSource::SetVolume(float left, float right)
300 {
301 // remote setvolume may not supported
302 float volume = 0.5;
303 CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!");
304
305 float leftVolume_ = left;
306 float rightVolume_ = right;
307 float half = 0.5;
308 if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
309 volume = rightVolume_;
310 } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
311 volume = leftVolume_;
312 } else {
313 volume = (leftVolume_ + rightVolume_) * half;
314 }
315
316 int32_t ret = audioCapture_->volume.SetVolume(reinterpret_cast<AudioHandle>(audioCapture_), volume);
317 AUDIO_INFO_LOG("remote setVolume(%{public}f, %{public}f):%{public}d", left, right, ret);
318 return ret;
319 }
320
GetVolume(float & left,float & right)321 int32_t RemoteAudioCapturerSource::GetVolume(float &left, float &right)
322 {
323 float val = 0.0;
324 audioCapture_->volume.GetVolume((AudioHandle)audioCapture_, &val);
325 left = val;
326 right = val;
327
328 return SUCCESS;
329 }
330
SetMute(bool isMute)331 int32_t RemoteAudioCapturerSource::SetMute(bool isMute)
332 {
333 int32_t ret;
334 CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!");
335
336 ret = audioCapture_->volume.SetMute((AudioHandle)audioCapture_, isMute);
337 if (ret != 0) {
338 AUDIO_ERR_LOG("SetMute failed from hdi");
339 }
340
341 micMuteState_ = isMute;
342 return SUCCESS;
343 }
344
GetMute(bool & isMute)345 int32_t RemoteAudioCapturerSource::GetMute(bool &isMute)
346 {
347 int32_t ret;
348 CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!");
349
350 bool isHdiMute = false;
351 ret = audioCapture_->volume.GetMute((AudioHandle)audioCapture_, &isHdiMute);
352 if (ret != 0) {
353 AUDIO_ERR_LOG("AudioCapturerSource::GetMute failed from hdi");
354 }
355
356 isMute = micMuteState_;
357 return SUCCESS;
358 }
359
SetInputPortPin(DeviceType inputDevice,AudioRouteNode & source)360 int32_t SetInputPortPin(DeviceType inputDevice, AudioRouteNode &source)
361 {
362 int32_t ret = SUCCESS;
363
364 switch (inputDevice) {
365 case DEVICE_TYPE_MIC:
366 source.ext.device.type = PIN_IN_MIC;
367 source.ext.device.desc = "pin_in_mic";
368 break;
369 case DEVICE_TYPE_WIRED_HEADSET:
370 source.ext.device.type = PIN_IN_HS_MIC;
371 source.ext.device.desc = "pin_in_hs_mic";
372 break;
373 case DEVICE_TYPE_USB_HEADSET:
374 source.ext.device.type = PIN_IN_USB_EXT;
375 source.ext.device.desc = "pin_in_usb_ext";
376 break;
377 default:
378 ret = ERR_NOT_SUPPORTED;
379 break;
380 }
381
382 return ret;
383 }
384
SetInputRoute(DeviceType inputDevice)385 int32_t RemoteAudioCapturerSource::SetInputRoute(DeviceType inputDevice)
386 {
387 AudioRouteNode source = {};
388 AudioRouteNode sink = {};
389
390 int32_t ret = SetInputPortPin(inputDevice, source);
391 if (ret != SUCCESS) {
392 AUDIO_ERR_LOG("AudioCapturerSource: OpenOutput FAILED: %{public}d", ret);
393 return ret;
394 }
395
396 source.portId = audioPort.portId;
397 source.role = AUDIO_PORT_SOURCE_ROLE;
398 source.type = AUDIO_PORT_DEVICE_TYPE;
399 source.ext.device.moduleId = 0;
400
401 sink.portId = 0;
402 sink.role = AUDIO_PORT_SINK_ROLE;
403 sink.type = AUDIO_PORT_MIX_TYPE;
404 sink.ext.mix.moduleId = 0;
405 sink.ext.mix.streamId = internalInputStreamId;
406
407 AudioRoute route = {
408 .sourcesNum = 1,
409 .sources = &source,
410 .sinksNum = 1,
411 .sinks = &sink,
412 };
413
414 if (audioAdapter_ == nullptr) {
415 AUDIO_ERR_LOG("SetInputRoute failed, audioAdapter_ is null");
416 return ERR_INVALID_PARAM;
417 }
418 ret = audioAdapter_->UpdateAudioRoute(audioAdapter_, &route, &routeHandle_);
419 AUDIO_DEBUG_LOG("UpdateAudioRoute returns: %{public}d", ret);
420 if (ret != 0) {
421 AUDIO_ERR_LOG("UpdateAudioRoute failed");
422 return ERR_OPERATION_FAILED;
423 }
424 return SUCCESS;
425 }
426
GetAudioCategory(AudioScene audioScene)427 AudioCategory GetAudioCategory(AudioScene audioScene)
428 {
429 AudioCategory audioCategory;
430 switch (audioScene) {
431 case AUDIO_SCENE_DEFAULT:
432 audioCategory = AUDIO_IN_MEDIA;
433 break;
434 case AUDIO_SCENE_RINGING:
435 audioCategory = AUDIO_IN_RINGTONE;
436 break;
437 case AUDIO_SCENE_PHONE_CALL:
438 audioCategory = AUDIO_IN_CALL;
439 break;
440 case AUDIO_SCENE_PHONE_CHAT:
441 audioCategory = AUDIO_IN_COMMUNICATION;
442 break;
443 default:
444 audioCategory = AUDIO_IN_MEDIA;
445 break;
446 }
447 AUDIO_DEBUG_LOG("RemoteAudioCapturerSource: Audio category returned is: %{public}d", audioCategory);
448
449 return audioCategory;
450 }
451
SetAudioScene(AudioScene audioScene,DeviceType activeDevice)452 int32_t RemoteAudioCapturerSource::SetAudioScene(AudioScene audioScene, DeviceType activeDevice)
453 {
454 CHECK_AND_RETURN_RET_LOG((audioCapture_ != nullptr), ERR_INVALID_HANDLE, "Audio capture Handle is nullptr!");
455 struct AudioSceneDescriptor scene;
456 scene.scene.id = GetAudioCategory(audioScene);
457 scene.desc.pins = PIN_IN_MIC;
458 if (audioCapture_->scene.SelectScene == nullptr) {
459 AUDIO_ERR_LOG("AudioCapturerSource: Select scene nullptr");
460 return ERR_OPERATION_FAILED;
461 }
462
463 AUDIO_INFO_LOG("AudioCapturerSource::SelectScene start");
464 int32_t ret = audioCapture_->scene.SelectScene((AudioHandle)audioCapture_, &scene);
465 AUDIO_INFO_LOG("AudioCapturerSource::SelectScene over");
466 if (ret < 0) {
467 AUDIO_ERR_LOG("AudioCapturerSource: Select scene FAILED: %{public}d", ret);
468 return ERR_OPERATION_FAILED;
469 }
470 AUDIO_INFO_LOG("AudioCapturerSource::Select audio scene SUCCESS: %{public}d", audioScene);
471 return SUCCESS;
472 }
473
GetTransactionId()474 uint64_t RemoteAudioCapturerSource::GetTransactionId()
475 {
476 AUDIO_INFO_LOG("RemoteAudioCapturerSource::GetTransactionId in");
477 return reinterpret_cast<uint64_t>(audioCapture_);
478 }
479
Stop(void)480 int32_t RemoteAudioCapturerSource::Stop(void)
481 {
482 AUDIO_INFO_LOG("RemoteAudioCapturerSource::Stop in");
483 int32_t ret;
484 if (started_ && audioCapture_ != nullptr) {
485 ret = audioCapture_->control.Stop(reinterpret_cast<AudioHandle>(audioCapture_));
486 if (ret < 0) {
487 AUDIO_ERR_LOG("Stop capture Failed");
488 return ERR_OPERATION_FAILED;
489 }
490 }
491 started_ = false;
492 return SUCCESS;
493 }
494
Pause(void)495 int32_t RemoteAudioCapturerSource::Pause(void)
496 {
497 int32_t ret;
498 if (started_ && audioCapture_ != nullptr) {
499 ret = audioCapture_->control.Pause(reinterpret_cast<AudioHandle>(audioCapture_));
500 if (ret != 0) {
501 AUDIO_ERR_LOG("pause capture Failed");
502 return ERR_OPERATION_FAILED;
503 }
504 }
505 paused_ = true;
506 return SUCCESS;
507 }
508
Resume(void)509 int32_t RemoteAudioCapturerSource::Resume(void)
510 {
511 int32_t ret;
512 if (paused_ && audioCapture_ != nullptr) {
513 ret = audioCapture_->control.Resume(reinterpret_cast<AudioHandle>(audioCapture_));
514 if (ret != 0) {
515 AUDIO_ERR_LOG("resume capture Failed");
516 return ERR_OPERATION_FAILED;
517 }
518 }
519 paused_ = false;
520 return SUCCESS;
521 }
522
Reset(void)523 int32_t RemoteAudioCapturerSource::Reset(void)
524 {
525 if (started_ && audioCapture_ != nullptr) {
526 audioCapture_->control.Flush(reinterpret_cast<AudioHandle>(audioCapture_));
527 }
528 return SUCCESS;
529 }
530
Flush(void)531 int32_t RemoteAudioCapturerSource::Flush(void)
532 {
533 if (started_ && audioCapture_ != nullptr) {
534 audioCapture_->control.Flush(reinterpret_cast<AudioHandle>(audioCapture_));
535 }
536 return SUCCESS;
537 }
538 } // namespace AudioStandard
539 } // namesapce OHOS
540
541