• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param, &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