1 /*
2 * Copyright (c) 2021-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 "media_log.h"
22 #include "audio_capturer_source.h"
23
24 using namespace std;
25
26 namespace OHOS {
27 namespace AudioStandard {
28 #ifdef CAPTURE_DUMP
29 const char *g_audioOutTestFilePath = "/data/local/tmp/audio_capture.pcm";
30 #endif // CAPTURE_DUMP
31
32 bool AudioCapturerSource::micMuteState_ = false;
33
AudioCapturerSource()34 AudioCapturerSource::AudioCapturerSource()
35 : capturerInited_(false), started_(false), paused_(false), leftVolume_(MAX_VOLUME_LEVEL),
36 rightVolume_(MAX_VOLUME_LEVEL), audioManager_(nullptr), audioAdapter_(nullptr), audioCapture_(nullptr)
37 {
38 attr_ = {};
39 #ifdef CAPTURE_DUMP
40 pfd = nullptr;
41 #endif // CAPTURE_DUMP
42 }
43
~AudioCapturerSource()44 AudioCapturerSource::~AudioCapturerSource()
45 {
46 DeInit();
47 }
48
GetInstance()49 AudioCapturerSource *AudioCapturerSource::GetInstance()
50 {
51 static AudioCapturerSource audioCapturer_;
52 return &audioCapturer_;
53 }
54
DeInit()55 void AudioCapturerSource::DeInit()
56 {
57 started_ = false;
58 capturerInited_ = false;
59
60 if ((audioCapture_ != nullptr) && (audioAdapter_ != nullptr)) {
61 audioAdapter_->DestroyCapture(audioAdapter_, audioCapture_);
62 }
63 audioCapture_ = nullptr;
64
65 if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
66 if (routeHandle_ != -1) {
67 audioAdapter_->ReleaseAudioRoute(audioAdapter_, routeHandle_);
68 }
69 audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
70 }
71 audioAdapter_ = nullptr;
72 audioManager_ = nullptr;
73 #ifdef CAPTURE_DUMP
74 if (pfd) {
75 fclose(pfd);
76 pfd = nullptr;
77 }
78 #endif // CAPTURE_DUMP
79 }
80
InitAttrsCapture(struct AudioSampleAttributes & attrs)81 void InitAttrsCapture(struct AudioSampleAttributes &attrs)
82 {
83 /* Initialization of audio parameters for playback */
84 attrs.format = AUDIO_FORMAT_PCM_16_BIT;
85 attrs.channelCount = AUDIO_CHANNELCOUNT;
86 attrs.sampleRate = AUDIO_SAMPLE_RATE_48K;
87 attrs.interleaved = true;
88 attrs.streamId = INTERNAL_INPUT_STREAM_ID;
89 attrs.type = AUDIO_IN_MEDIA;
90 attrs.period = DEEP_BUFFER_CAPTURE_PERIOD_SIZE;
91 attrs.frameSize = PCM_16_BIT * attrs.channelCount / PCM_8_BIT;
92 attrs.isBigEndian = false;
93 attrs.isSignedData = true;
94 attrs.startThreshold = DEEP_BUFFER_CAPTURE_PERIOD_SIZE / (attrs.frameSize);
95 attrs.stopThreshold = INT_32_MAX;
96 /* 16 * 1024 */
97 attrs.silenceThreshold = AUDIO_BUFF_SIZE;
98 }
99
SwitchAdapterCapture(struct AudioAdapterDescriptor * descs,int32_t size,const std::string & adapterNameCase,enum AudioPortDirection portFlag,struct AudioPort & capturePort)100 int32_t SwitchAdapterCapture(struct AudioAdapterDescriptor *descs, int32_t size, const std::string &adapterNameCase,
101 enum AudioPortDirection portFlag, struct AudioPort &capturePort)
102 {
103 if (descs == nullptr) {
104 return ERROR;
105 }
106
107 for (int32_t index = 0; index < size; index++) {
108 struct AudioAdapterDescriptor *desc = &descs[index];
109 if (desc == nullptr) {
110 continue;
111 }
112 if (!adapterNameCase.compare(desc->adapterName)) {
113 for (uint32_t port = 0; port < desc->portNum; port++) {
114 // Only find out the port of out in the sound card
115 if (desc->ports[port].dir == portFlag) {
116 capturePort = desc->ports[port];
117 return index;
118 }
119 }
120 }
121 }
122 MEDIA_ERR_LOG("SwitchAdapterCapture Fail");
123
124 return ERR_INVALID_INDEX;
125 }
126
InitAudioManager()127 int32_t AudioCapturerSource::InitAudioManager()
128 {
129 MEDIA_INFO_LOG("AudioCapturerSource: Initialize audio proxy manager");
130
131 audioManager_ = GetAudioProxyManagerFuncs();
132 if (audioManager_ == nullptr) {
133 return ERR_INVALID_HANDLE;
134 }
135
136 return 0;
137 }
138
CreateCapture(struct AudioPort & capturePort)139 int32_t AudioCapturerSource::CreateCapture(struct AudioPort &capturePort)
140 {
141 int32_t ret;
142 struct AudioSampleAttributes param;
143 // User needs to set
144 InitAttrsCapture(param);
145 param.sampleRate = attr_.sampleRate;
146 param.format = attr_.format;
147 param.isBigEndian = attr_.isBigEndian;
148 param.channelCount = attr_.channel;
149 param.silenceThreshold = attr_.bufferSize;
150 param.frameSize = param.format * param.channelCount;
151 param.startThreshold = DEEP_BUFFER_CAPTURE_PERIOD_SIZE / (param.frameSize);
152
153 struct AudioDeviceDescriptor deviceDesc;
154 deviceDesc.portId = capturePort.portId;
155 deviceDesc.pins = PIN_IN_MIC;
156 deviceDesc.desc = nullptr;
157
158 ret = audioAdapter_->CreateCapture(audioAdapter_, &deviceDesc, ¶m, &audioCapture_);
159 if (audioCapture_ == nullptr || ret < 0) {
160 MEDIA_ERR_LOG("Create capture failed");
161 return ERR_NOT_STARTED;
162 }
163
164 return 0;
165 }
166
GetAndLoadAdapter(void)167 int32_t AudioCapturerSource::GetAndLoadAdapter(void)
168 {
169 int32_t size = 0;
170 struct AudioAdapterDescriptor *descs = nullptr;
171 int32_t ret = audioManager_->GetAllAdapters(audioManager_, &descs, &size);
172 // adapters is 0~3
173 if (size > MAX_AUDIO_ADAPTER_NUM || size == 0 || descs == nullptr || ret != 0) {
174 MEDIA_ERR_LOG("Get adapters Fail");
175 return ERR_NOT_STARTED;
176 }
177
178 // Get qualified sound card and port
179 #ifdef PRODUCT_Hi37XX
180 string adapterNameCase = "primary"; // Set sound card information
181 #else
182 string adapterNameCase = "internal";
183 #endif
184 int32_t index = SwitchAdapterCapture(descs, size, adapterNameCase, PORT_IN, audioPort);
185 if (index < 0) {
186 MEDIA_ERR_LOG("Switch Adapter Capture Fail");
187 return ERR_NOT_STARTED;
188 }
189
190 struct AudioAdapterDescriptor *desc = &descs[index];
191 if (audioManager_->LoadAdapter(audioManager_, desc, &audioAdapter_) != 0) {
192 MEDIA_ERR_LOG("Load Adapter Fail");
193 return ERR_NOT_STARTED;
194 }
195 if (audioAdapter_ == nullptr) {
196 MEDIA_ERR_LOG("Load audio device failed");
197 return ERR_NOT_STARTED;
198 }
199 return SUCCESS;
200 }
201
Init(AudioSourceAttr & attr)202 int32_t AudioCapturerSource::Init(AudioSourceAttr &attr)
203 {
204 attr_ = attr;
205 if (InitAudioManager() != 0) {
206 MEDIA_ERR_LOG("Init audio manager Fail");
207 return ERR_INVALID_HANDLE;
208 }
209
210 int32_t ret = GetAndLoadAdapter();
211 if (ret != SUCCESS) {
212 return ret;
213 }
214
215 // Inittialization port information, can fill through mode and other parameters
216 ret = audioAdapter_->InitAllPorts(audioAdapter_);
217 if (ret != 0) {
218 MEDIA_ERR_LOG("InitAllPorts failed");
219 return ERR_DEVICE_INIT;
220 }
221
222 if (CreateCapture(audioPort) != 0) {
223 MEDIA_ERR_LOG("Create capture failed");
224 return ERR_NOT_STARTED;
225 }
226
227 #ifdef PRODUCT_M40
228 ret = OpenInput(DEVICE_TYPE_MIC);
229 if (ret < 0) {
230 MEDIA_ERR_LOG("AudioRendererSink: update route FAILED: %{public}d", ret);
231 }
232 #endif
233
234 capturerInited_ = true;
235
236 #ifdef CAPTURE_DUMP
237 pfd = fopen(g_audioOutTestFilePath, "wb+");
238 if (pfd == nullptr) {
239 MEDIA_ERR_LOG("Error opening pcm test file!");
240 }
241 #endif // CAPTURE_DUMP
242
243 return SUCCESS;
244 }
245
CaptureFrame(char * frame,uint64_t requestBytes,uint64_t & replyBytes)246 int32_t AudioCapturerSource::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes)
247 {
248 int32_t ret;
249 if (audioCapture_ == nullptr) {
250 MEDIA_ERR_LOG("Audio capture Handle is nullptr!");
251 return ERR_INVALID_HANDLE;
252 }
253
254 ret = audioCapture_->CaptureFrame(audioCapture_, frame, requestBytes, &replyBytes);
255 if (ret < 0) {
256 MEDIA_ERR_LOG("Capture Frame Fail");
257 return ERR_READ_FAILED;
258 }
259
260 #ifdef CAPTURE_DUMP
261 size_t writeResult = fwrite(frame, replyBytes, 1, pfd);
262 if (writeResult != replyBytes) {
263 MEDIA_ERR_LOG("Failed to write the file.");
264 }
265 #endif // CAPTURE_DUMP
266
267 return SUCCESS;
268 }
269
Start(void)270 int32_t AudioCapturerSource::Start(void)
271 {
272 int32_t ret;
273 if (!started_) {
274 ret = audioCapture_->control.Start((AudioHandle)audioCapture_);
275 if (ret < 0) {
276 return ERR_NOT_STARTED;
277 }
278 started_ = true;
279 }
280
281 return SUCCESS;
282 }
283
SetVolume(float left,float right)284 int32_t AudioCapturerSource::SetVolume(float left, float right)
285 {
286 float volume;
287 if (audioCapture_ == nullptr) {
288 MEDIA_ERR_LOG("AudioCapturerSource::SetVolume failed audioCapture_ null");
289 return ERR_INVALID_HANDLE;
290 }
291
292 leftVolume_ = left;
293 rightVolume_ = right;
294 if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
295 volume = rightVolume_;
296 } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
297 volume = leftVolume_;
298 } else {
299 volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
300 }
301
302 audioCapture_->volume.SetVolume(reinterpret_cast<AudioHandle>(audioCapture_), volume);
303
304 return SUCCESS;
305 }
306
GetVolume(float & left,float & right)307 int32_t AudioCapturerSource::GetVolume(float &left, float &right)
308 {
309 float val = 0.0;
310 audioCapture_->volume.GetVolume((AudioHandle)audioCapture_, &val);
311 left = val;
312 right = val;
313
314 return SUCCESS;
315 }
316
SetMute(bool isMute)317 int32_t AudioCapturerSource::SetMute(bool isMute)
318 {
319 int32_t ret;
320 if (audioCapture_ == nullptr) {
321 MEDIA_ERR_LOG("AudioCapturerSource::SetMute failed audioCapture_ handle is null!");
322 return ERR_INVALID_HANDLE;
323 }
324
325 ret = audioCapture_->volume.SetMute((AudioHandle)audioCapture_, isMute);
326 if (ret != 0) {
327 MEDIA_ERR_LOG("AudioCapturerSource::SetMute failed from hdi");
328 }
329
330 micMuteState_ = isMute;
331
332 return SUCCESS;
333 }
334
GetMute(bool & isMute)335 int32_t AudioCapturerSource::GetMute(bool &isMute)
336 {
337 int32_t ret;
338 if (audioCapture_ == nullptr) {
339 MEDIA_ERR_LOG("AudioCapturerSource::GetMute failed audioCapture_ handle is null!");
340 return ERR_INVALID_HANDLE;
341 }
342
343 bool isHdiMute = false;
344 ret = audioCapture_->volume.GetMute((AudioHandle)audioCapture_, &isHdiMute);
345 if (ret != 0) {
346 MEDIA_ERR_LOG("AudioCapturerSource::GetMute failed from hdi");
347 }
348
349 isMute = micMuteState_;
350
351 return SUCCESS;
352 }
353
354 #ifdef PRODUCT_M40
GetAudioCategory(AudioScene audioScene)355 static AudioCategory GetAudioCategory(AudioScene audioScene)
356 {
357 AudioCategory audioCategory;
358 switch (audioScene) {
359 case AUDIO_SCENE_DEFAULT:
360 audioCategory = AUDIO_IN_MEDIA;
361 break;
362 case AUDIO_SCENE_RINGING:
363 audioCategory = AUDIO_IN_RINGTONE;
364 break;
365 case AUDIO_SCENE_PHONE_CALL:
366 audioCategory = AUDIO_IN_CALL;
367 break;
368 case AUDIO_SCENE_PHONE_CHAT:
369 audioCategory = AUDIO_IN_COMMUNICATION;
370 break;
371 default:
372 audioCategory = AUDIO_IN_MEDIA;
373 break;
374 }
375 MEDIA_DEBUG_LOG("AudioCapturerSource: Audio category returned is: %{public}d", audioCategory);
376
377 return audioCategory;
378 }
379 #endif
380
SetInputPortPin(DeviceType inputDevice,AudioRouteNode & source)381 static int32_t SetInputPortPin(DeviceType inputDevice, AudioRouteNode &source)
382 {
383 int32_t ret = SUCCESS;
384
385 switch (inputDevice) {
386 case DEVICE_TYPE_MIC:
387 source.ext.device.type = PIN_IN_MIC;
388 source.ext.device.desc = "pin_in_mic";
389 break;
390 case DEVICE_TYPE_WIRED_HEADSET:
391 source.ext.device.type = PIN_IN_HS_MIC;
392 source.ext.device.desc = "pin_in_hs_mic";
393 break;
394 case DEVICE_TYPE_USB_HEADSET:
395 source.ext.device.type = PIN_IN_USB_EXT;
396 source.ext.device.desc = "pin_in_usb_ext";
397 break;
398 default:
399 ret = ERR_NOT_SUPPORTED;
400 break;
401 }
402
403 return ret;
404 }
405
OpenInput(DeviceType inputDevice)406 int32_t AudioCapturerSource::OpenInput(DeviceType inputDevice)
407 {
408 AudioRouteNode source = {};
409 AudioRouteNode sink = {};
410
411 int32_t ret = SetInputPortPin(inputDevice, source);
412 if (ret != SUCCESS) {
413 MEDIA_ERR_LOG("AudioCapturerSource: OpenOutput FAILED: %{public}d", ret);
414 return ret;
415 }
416
417 source.portId = audioPort.portId;
418 source.role = AUDIO_PORT_SOURCE_ROLE;
419 source.type = AUDIO_PORT_DEVICE_TYPE;
420 source.ext.device.moduleId = 0;
421
422 sink.portId = 0;
423 sink.role = AUDIO_PORT_SINK_ROLE;
424 sink.type = AUDIO_PORT_MIX_TYPE;
425 sink.ext.mix.moduleId = 0;
426 sink.ext.mix.streamId = INTERNAL_INPUT_STREAM_ID;
427
428 AudioRoute route = {
429 .sourcesNum = 1,
430 .sources = &source,
431 .sinksNum = 1,
432 .sinks = &sink,
433 };
434
435 ret = audioAdapter_->UpdateAudioRoute(audioAdapter_, &route, &routeHandle_);
436 MEDIA_DEBUG_LOG("AudioCapturerSource: UpdateAudioRoute returns: %{public}d", ret);
437 if (ret != 0) {
438 MEDIA_ERR_LOG("AudioCapturerSource: UpdateAudioRoute failed");
439 return ERR_OPERATION_FAILED;
440 }
441
442 return SUCCESS;
443 }
444
SetAudioScene(AudioScene audioScene)445 int32_t AudioCapturerSource::SetAudioScene(AudioScene audioScene)
446 {
447 MEDIA_INFO_LOG("AudioCapturerSource::SetAudioScene in");
448 CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene <= AUDIO_SCENE_PHONE_CHAT,
449 ERR_INVALID_PARAM, "invalid audioScene");
450 if (audioCapture_ == nullptr) {
451 MEDIA_ERR_LOG("AudioCapturerSource::SetAudioScene failed audioCapture_ handle is null!");
452 return ERR_INVALID_HANDLE;
453 }
454
455 #ifdef PRODUCT_M40
456 int32_t ret = OpenInput(DEVICE_TYPE_MIC);
457 if (ret < 0) {
458 MEDIA_ERR_LOG("AudioCapturerSource: Update route FAILED: %{public}d", ret);
459 }
460
461 struct AudioSceneDescriptor scene;
462 scene.scene.id = GetAudioCategory(audioScene);
463 scene.desc.pins = PIN_IN_MIC;
464 if (audioCapture_->scene.SelectScene == nullptr) {
465 MEDIA_ERR_LOG("AudioCapturerSource: Select scene nullptr");
466 return ERR_OPERATION_FAILED;
467 }
468
469 ret = audioCapture_->scene.SelectScene((AudioHandle)audioCapture_, &scene);
470 if (ret < 0) {
471 MEDIA_ERR_LOG("AudioCapturerSource: Select scene FAILED: %{public}d", ret);
472 return ERR_OPERATION_FAILED;
473 }
474 #endif
475
476 MEDIA_INFO_LOG("AudioCapturerSource::Select audio scene SUCCESS: %{public}d", audioScene);
477 return SUCCESS;
478 }
479
Stop(void)480 int32_t AudioCapturerSource::Stop(void)
481 {
482 int32_t ret;
483 if (started_ && audioCapture_ != nullptr) {
484 ret = audioCapture_->control.Stop(reinterpret_cast<AudioHandle>(audioCapture_));
485 if (ret < 0) {
486 MEDIA_ERR_LOG("Stop capture Failed");
487 return ERR_OPERATION_FAILED;
488 }
489 }
490 started_ = false;
491
492 return SUCCESS;
493 }
494
Pause(void)495 int32_t AudioCapturerSource::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 MEDIA_ERR_LOG("pause capture Failed");
502 return ERR_OPERATION_FAILED;
503 }
504 }
505 paused_ = true;
506
507 return SUCCESS;
508 }
509
Resume(void)510 int32_t AudioCapturerSource::Resume(void)
511 {
512 int32_t ret;
513 if (paused_ && audioCapture_ != nullptr) {
514 ret = audioCapture_->control.Resume(reinterpret_cast<AudioHandle>(audioCapture_));
515 if (ret != 0) {
516 MEDIA_ERR_LOG("resume capture Failed");
517 return ERR_OPERATION_FAILED;
518 }
519 }
520 paused_ = false;
521
522 return SUCCESS;
523 }
524
Reset(void)525 int32_t AudioCapturerSource::Reset(void)
526 {
527 if (started_ && audioCapture_ != nullptr) {
528 audioCapture_->control.Flush(reinterpret_cast<AudioHandle>(audioCapture_));
529 }
530
531 return SUCCESS;
532 }
533
Flush(void)534 int32_t AudioCapturerSource::Flush(void)
535 {
536 if (started_ && audioCapture_ != nullptr) {
537 audioCapture_->control.Flush(reinterpret_cast<AudioHandle>(audioCapture_));
538 }
539
540 return SUCCESS;
541 }
542 } // namespace AudioStandard
543 } // namesapce OHOS
544
545 #ifdef __cplusplus
546 extern "C" {
547 #endif
548
549 using namespace OHOS::AudioStandard;
550
551 AudioCapturerSource *g_audioCaptureSourceInstance = AudioCapturerSource::GetInstance();
552
AudioCapturerSourceInit(AudioSourceAttr * attr)553 int32_t AudioCapturerSourceInit(AudioSourceAttr *attr)
554 {
555 int32_t ret;
556
557 if (g_audioCaptureSourceInstance->capturerInited_)
558 return SUCCESS;
559
560 ret = g_audioCaptureSourceInstance->Init(*attr);
561
562 return ret;
563 }
564
AudioCapturerSourceDeInit()565 void AudioCapturerSourceDeInit()
566 {
567 if (g_audioCaptureSourceInstance->capturerInited_)
568 g_audioCaptureSourceInstance->DeInit();
569 }
570
AudioCapturerSourceStop()571 int32_t AudioCapturerSourceStop()
572 {
573 int32_t ret;
574
575 if (!g_audioCaptureSourceInstance->capturerInited_)
576 return SUCCESS;
577
578 ret = g_audioCaptureSourceInstance->Stop();
579
580 return ret;
581 }
582
AudioCapturerSourceStart()583 int32_t AudioCapturerSourceStart()
584 {
585 int32_t ret;
586
587 if (!g_audioCaptureSourceInstance->capturerInited_) {
588 MEDIA_ERR_LOG("audioCapturer Not Inited! Init the capturer first\n");
589 return ERR_DEVICE_INIT;
590 }
591
592 ret = g_audioCaptureSourceInstance->Start();
593
594 return ret;
595 }
596
AudioCapturerSourceFrame(char * frame,uint64_t requestBytes,uint64_t & replyBytes)597 int32_t AudioCapturerSourceFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes)
598 {
599 int32_t ret;
600
601 if (!g_audioCaptureSourceInstance->capturerInited_) {
602 MEDIA_ERR_LOG("audioCapturer Not Inited! Init the capturer first\n");
603 return ERR_DEVICE_INIT;
604 }
605
606 ret = g_audioCaptureSourceInstance->CaptureFrame(frame, requestBytes, replyBytes);
607
608 return ret;
609 }
610
AudioCapturerSourceSetVolume(float left,float right)611 int32_t AudioCapturerSourceSetVolume(float left, float right)
612 {
613 int32_t ret;
614
615 if (!g_audioCaptureSourceInstance->capturerInited_) {
616 MEDIA_ERR_LOG("audioCapturer Not Inited! Init the capturer first\n");
617 return ERR_DEVICE_INIT;
618 }
619
620 ret = g_audioCaptureSourceInstance->SetVolume(left, right);
621
622 return ret;
623 }
624
AudioCapturerSourceGetVolume(float * left,float * right)625 int32_t AudioCapturerSourceGetVolume(float *left, float *right)
626 {
627 int32_t ret;
628
629 if (!g_audioCaptureSourceInstance->capturerInited_) {
630 MEDIA_ERR_LOG("audioCapturer Not Inited! Init the capturer first\n");
631 return ERR_DEVICE_INIT;
632 }
633 ret = g_audioCaptureSourceInstance->GetVolume(*left, *right);
634
635 return ret;
636 }
637
AudioCapturerSourceIsMuteRequired(void)638 bool AudioCapturerSourceIsMuteRequired(void)
639 {
640 return AudioCapturerSource::micMuteState_;
641 }
642
AudioCapturerSourceSetMute(bool isMute)643 int32_t AudioCapturerSourceSetMute(bool isMute)
644 {
645 int32_t ret;
646
647 if (!g_audioCaptureSourceInstance->capturerInited_) {
648 MEDIA_ERR_LOG("audioCapturer Not Inited! Init the capturer first\n");
649 return ERR_DEVICE_INIT;
650 }
651
652 ret = g_audioCaptureSourceInstance->SetMute(isMute);
653
654 return ret;
655 }
656 #ifdef __cplusplus
657 }
658 #endif
659