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