• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioEcManager"
17 #endif
18 
19 #include "audio_ec_manager.h"
20 #include "parameter.h"
21 #include "parameters.h"
22 
23 #include "audio_server_proxy.h"
24 #include "audio_policy_utils.h"
25 #include "audio_pipe_manager.h"
26 
27 namespace OHOS {
28 namespace AudioStandard {
29 constexpr int32_t MS_PER_S = 1000;
30 static const unsigned int BUFFER_CALC_20MS = 20;
31 const uint32_t PC_MIC_CHANNEL_NUM = 4;
32 const uint32_t HEADPHONE_CHANNEL_NUM = 2;
33 static const char* PIPE_PRIMARY_OUTPUT = "primary_output";
34 static const char* PIPE_PRIMARY_INPUT = "primary_input";
35 static const char* PIPE_USB_ARM_OUTPUT = "usb_arm_output";
36 static const char* PIPE_USB_ARM_INPUT = "usb_arm_input";
37 static const char* PIPE_DP_OUTPUT = "dp_output";
38 static const char* PIPE_ACCESSORY_INPUT = "accessory_input";
39 const float RENDER_FRAME_INTERVAL_IN_SECONDS = 0.02;
40 
41 static std::map<std::string, uint32_t> formatFromParserStrToEnum = {
42     {"s16le", SAMPLE_S16LE},
43     {"s24le", SAMPLE_S24LE},
44     {"s32le", SAMPLE_S32LE},
45 };
46 
47 static const std::vector<DeviceType> MIC_REF_DEVICES = {
48     DEVICE_TYPE_WIRED_HEADSET,
49     DEVICE_TYPE_USB_HEADSET,
50     DEVICE_TYPE_BLUETOOTH_SCO,
51     DEVICE_TYPE_USB_ARM_HEADSET,
52     DEVICE_TYPE_BLUETOOTH_A2DP_IN
53 };
54 
55 static std::map<std::string, AudioSampleFormat> formatStrToEnum = {
56     {"s8", SAMPLE_U8},
57     {"s16", SAMPLE_S16LE},
58     {"s24", SAMPLE_S24LE},
59     {"s32", SAMPLE_S32LE},
60     {"s16le", SAMPLE_S16LE},
61     {"s24le", SAMPLE_S24LE},
62     {"s32le", SAMPLE_S32LE},
63 };
64 
65 
66 static const std::map<std::pair<DeviceType, DeviceType>, EcType> DEVICE_TO_EC_TYPE = {
67     {{DEVICE_TYPE_MIC, DEVICE_TYPE_SPEAKER}, EC_TYPE_SAME_ADAPTER},
68     {{DEVICE_TYPE_MIC, DEVICE_TYPE_USB_HEADSET}, EC_TYPE_SAME_ADAPTER},
69     {{DEVICE_TYPE_MIC, DEVICE_TYPE_WIRED_HEADSET}, EC_TYPE_SAME_ADAPTER},
70     {{DEVICE_TYPE_MIC, DEVICE_TYPE_USB_ARM_HEADSET}, EC_TYPE_DIFF_ADAPTER},
71     {{DEVICE_TYPE_MIC, DEVICE_TYPE_BLUETOOTH_SCO}, EC_TYPE_SAME_ADAPTER},
72     {{DEVICE_TYPE_MIC, DEVICE_TYPE_DP}, EC_TYPE_DIFF_ADAPTER},
73 
74     {{DEVICE_TYPE_USB_HEADSET, DEVICE_TYPE_SPEAKER}, EC_TYPE_SAME_ADAPTER},
75     {{DEVICE_TYPE_USB_HEADSET, DEVICE_TYPE_USB_HEADSET}, EC_TYPE_SAME_ADAPTER},
76     {{DEVICE_TYPE_USB_HEADSET, DEVICE_TYPE_WIRED_HEADSET}, EC_TYPE_SAME_ADAPTER},
77     {{DEVICE_TYPE_USB_HEADSET, DEVICE_TYPE_USB_ARM_HEADSET}, EC_TYPE_DIFF_ADAPTER},
78     {{DEVICE_TYPE_USB_HEADSET, DEVICE_TYPE_BLUETOOTH_SCO}, EC_TYPE_DIFF_ADAPTER},
79     {{DEVICE_TYPE_USB_HEADSET, DEVICE_TYPE_DP}, EC_TYPE_DIFF_ADAPTER},
80 
81     {{DEVICE_TYPE_WIRED_HEADSET, DEVICE_TYPE_SPEAKER}, EC_TYPE_SAME_ADAPTER},
82     {{DEVICE_TYPE_WIRED_HEADSET, DEVICE_TYPE_USB_HEADSET}, EC_TYPE_SAME_ADAPTER},
83     {{DEVICE_TYPE_WIRED_HEADSET, DEVICE_TYPE_WIRED_HEADSET}, EC_TYPE_SAME_ADAPTER},
84     {{DEVICE_TYPE_WIRED_HEADSET, DEVICE_TYPE_USB_ARM_HEADSET}, EC_TYPE_DIFF_ADAPTER},
85     {{DEVICE_TYPE_WIRED_HEADSET, DEVICE_TYPE_BLUETOOTH_SCO}, EC_TYPE_DIFF_ADAPTER},
86     {{DEVICE_TYPE_WIRED_HEADSET, DEVICE_TYPE_DP}, EC_TYPE_DIFF_ADAPTER},
87 
88     {{DEVICE_TYPE_USB_ARM_HEADSET, DEVICE_TYPE_SPEAKER}, EC_TYPE_DIFF_ADAPTER},
89     {{DEVICE_TYPE_USB_ARM_HEADSET, DEVICE_TYPE_USB_HEADSET}, EC_TYPE_DIFF_ADAPTER},
90     {{DEVICE_TYPE_USB_ARM_HEADSET, DEVICE_TYPE_WIRED_HEADSET}, EC_TYPE_DIFF_ADAPTER},
91     {{DEVICE_TYPE_USB_ARM_HEADSET, DEVICE_TYPE_USB_ARM_HEADSET}, EC_TYPE_SAME_ADAPTER},
92     {{DEVICE_TYPE_USB_ARM_HEADSET, DEVICE_TYPE_BLUETOOTH_SCO}, EC_TYPE_DIFF_ADAPTER},
93     {{DEVICE_TYPE_USB_ARM_HEADSET, DEVICE_TYPE_DP}, EC_TYPE_DIFF_ADAPTER},
94 
95     {{DEVICE_TYPE_BLUETOOTH_SCO, DEVICE_TYPE_SPEAKER}, EC_TYPE_SAME_ADAPTER},
96     {{DEVICE_TYPE_BLUETOOTH_SCO, DEVICE_TYPE_USB_HEADSET}, EC_TYPE_SAME_ADAPTER},
97     {{DEVICE_TYPE_BLUETOOTH_SCO, DEVICE_TYPE_WIRED_HEADSET}, EC_TYPE_SAME_ADAPTER},
98     {{DEVICE_TYPE_BLUETOOTH_SCO, DEVICE_TYPE_USB_ARM_HEADSET}, EC_TYPE_DIFF_ADAPTER},
99     {{DEVICE_TYPE_BLUETOOTH_SCO, DEVICE_TYPE_BLUETOOTH_SCO}, EC_TYPE_SAME_ADAPTER},
100     {{DEVICE_TYPE_BLUETOOTH_SCO, DEVICE_TYPE_DP}, EC_TYPE_DIFF_ADAPTER},
101 
102     {{DEVICE_TYPE_ACCESSORY, DEVICE_TYPE_SPEAKER}, EC_TYPE_DIFF_ADAPTER},
103 };
104 
GetEncryptAddr(const std::string & addr)105 static std::string GetEncryptAddr(const std::string &addr)
106 {
107     const int32_t START_POS = 6;
108     const int32_t END_POS = 13;
109     const int32_t ADDRESS_STR_LEN = 17;
110     if (addr.empty() || addr.length() != ADDRESS_STR_LEN) {
111         return std::string("");
112     }
113     std::string tmp = "**:**:**:**:**:**";
114     std::string out = addr;
115     for (int i = START_POS; i <= END_POS; i++) {
116         out[i] = tmp[i];
117     }
118     return out;
119 }
120 
ParseAudioFormat(string format)121 static string ParseAudioFormat(string format)
122 {
123     if (format == "AUDIO_FORMAT_PCM_16_BIT") {
124         return "s16le";
125     } else if (format == "AUDIO_FORMAT_PCM_24_BIT" || format == "AUDIO_FORMAT_PCM_24_BIT_PACKED") {
126         return "s24le";
127     } else if (format == "AUDIO_FORMAT_PCM_32_BIT") {
128         return "s32le";
129     } else {
130         return "s16le";
131     }
132 }
133 
GetUsbModuleInfo(string deviceInfo,AudioModuleInfo & moduleInfo)134 static void GetUsbModuleInfo(string deviceInfo, AudioModuleInfo &moduleInfo)
135 {
136     if (moduleInfo.role == "sink") {
137         auto sinkRate_begin = deviceInfo.find("sink_rate:");
138         auto sinkRate_end = deviceInfo.find_first_of(";", sinkRate_begin);
139         moduleInfo.rate = deviceInfo.substr(sinkRate_begin + std::strlen("sink_rate:"),
140             sinkRate_end - sinkRate_begin - std::strlen("sink_rate:"));
141         auto sinkFormat_begin = deviceInfo.find("sink_format:");
142         auto sinkFormat_end = deviceInfo.find_first_of(";", sinkFormat_begin);
143         string format = deviceInfo.substr(sinkFormat_begin + std::strlen("sink_format:"),
144             sinkFormat_end - sinkFormat_begin - std::strlen("sink_format:"));
145         moduleInfo.format = ParseAudioFormat(format);
146     } else {
147         auto sourceRate_begin = deviceInfo.find("source_rate:");
148         auto sourceRate_end = deviceInfo.find_first_of(";", sourceRate_begin);
149         moduleInfo.rate = deviceInfo.substr(sourceRate_begin + std::strlen("source_rate:"),
150             sourceRate_end - sourceRate_begin - std::strlen("source_rate:"));
151         auto sourceFormat_begin = deviceInfo.find("source_format:");
152         auto sourceFormat_end = deviceInfo.find_first_of(";", sourceFormat_begin);
153         string format = deviceInfo.substr(sourceFormat_begin + std::strlen("source_format:"),
154             sourceFormat_end - sourceFormat_begin - std::strlen("source_format:"));
155         moduleInfo.format = ParseAudioFormat(format);
156     }
157 
158     if (!moduleInfo.rate.empty() && !moduleInfo.format.empty() && !moduleInfo.channels.empty()) {
159         uint32_t rateValue = 0;
160         uint32_t channelValue = 0;
161         CHECK_AND_RETURN_LOG(StringConverter(moduleInfo.rate, rateValue),
162             "convert invalid moduleInfo.rate: %{public}s", moduleInfo.rate.c_str());
163         CHECK_AND_RETURN_LOG(StringConverter(moduleInfo.channels, channelValue),
164             "convert invalid moduleInfo.channels: %{public}s", moduleInfo.channels.c_str());
165 
166         uint32_t bufferSize = rateValue * channelValue *
167             AudioPolicyUtils::GetInstance().PcmFormatToBytes(static_cast<AudioSampleFormat>(
168                 formatFromParserStrToEnum[moduleInfo.format])) * BUFFER_CALC_20MS / static_cast<uint32_t>(MS_PER_S);
169         moduleInfo.bufferSize = std::to_string(bufferSize);
170     }
171 }
172 
Init(int32_t ecEnableState,int32_t micRefEnableState)173 void AudioEcManager::Init(int32_t ecEnableState, int32_t micRefEnableState)
174 {
175     isEcFeatureEnable_ = ecEnableState != 0;
176     isMicRefFeatureEnable_ = micRefEnableState != 0;
177 }
178 
CloseNormalSource()179 void AudioEcManager::CloseNormalSource()
180 {
181     AUDIO_INFO_LOG("close all sources");
182     audioIOHandleMap_.ClosePortAndEraseIOHandle(BLUETOOTH_MIC);
183     audioIOHandleMap_.ClosePortAndEraseIOHandle(PRIMARY_MIC);
184     if (isEcFeatureEnable_) {
185         audioIOHandleMap_.ClosePortAndEraseIOHandle(USB_MIC);
186     }
187     normalSourceOpened_ = SOURCE_TYPE_INVALID;
188 }
189 
UpdateEnhanceEffectState(SourceType source)190 void AudioEcManager::UpdateEnhanceEffectState(SourceType source)
191 {
192     AudioEnhancePropertyArray enhancePropertyArray = {};
193     std::shared_ptr<AudioDeviceDescriptor> inputDesc = audioRouterCenter_.FetchInputDevice(source, -1);
194     CHECK_AND_RETURN_LOG(inputDesc != nullptr, "inputDesc is nullptr");
195     int32_t ret = AudioServerProxy::GetInstance().GetAudioEnhancePropertyProxy(enhancePropertyArray,
196         inputDesc->deviceType_);
197     if (ret != SUCCESS) {
198         AUDIO_ERR_LOG("get enhance property fail, ret: %{public}d", ret);
199         return;
200     }
201     std::string recordProp = "";
202     std::string voipUpProp = "";
203     for (const AudioEnhanceProperty &prop : enhancePropertyArray.property) {
204         if (prop.enhanceClass == "record") {
205             recordProp = prop.enhanceProp;
206         }
207         if (prop.enhanceClass == "voip_up") {
208             voipUpProp = prop.enhanceProp;
209         }
210     }
211     isMicRefRecordOn_ = (recordProp == "NRON");
212     isMicRefVoipUpOn_ = (voipUpProp == "PNR");
213 
214     AUDIO_INFO_LOG("ecEnableState: %{public}d, micRefEnableState: %{public}d, "
215         "isMicRefRecordOn_: %{public}d, isMicRefVoipUp: %{public}d",
216         isEcFeatureEnable_, isMicRefFeatureEnable_, isMicRefRecordOn_, isMicRefVoipUpOn_);
217 }
218 
UpdateStreamCommonInfo(AudioModuleInfo & moduleInfo,PipeStreamPropInfo & targetInfo,SourceType sourceType)219 void AudioEcManager::UpdateStreamCommonInfo(AudioModuleInfo &moduleInfo, PipeStreamPropInfo &targetInfo,
220     SourceType sourceType)
221 {
222     if (!isEcFeatureEnable_) {
223         moduleInfo = primaryMicModuleInfo_;
224         // current layout represents the number of channel. This will need to be modify in the future.
225         moduleInfo.channels = std::to_string(targetInfo.channels_);
226         moduleInfo.rate = std::to_string(targetInfo.sampleRate_);
227         moduleInfo.bufferSize = std::to_string(targetInfo.bufferSize_);
228         moduleInfo.format = AudioDefinitionPolicyUtils::enumToFormatStr[targetInfo.format_];
229         moduleInfo.sourceType = std::to_string(sourceType);
230     } else {
231         shared_ptr<AudioDeviceDescriptor> inputDesc = audioRouterCenter_.FetchInputDevice(sourceType, -1);
232         if (inputDesc != nullptr && inputDesc->deviceType_ == DEVICE_TYPE_USB_ARM_HEADSET) {
233             moduleInfo = usbSourceModuleInfo_;
234             moduleInfo.sourceType = std::to_string(sourceType);
235         } else {
236             moduleInfo = primaryMicModuleInfo_;
237             // current layout represents the number of channel. This will need to be modify in the future.
238             moduleInfo.channels = std::to_string(targetInfo.channels_);
239             moduleInfo.rate = std::to_string(targetInfo.sampleRate_);
240             moduleInfo.bufferSize = std::to_string(targetInfo.bufferSize_);
241             moduleInfo.format = AudioDefinitionPolicyUtils::enumToFormatStr[targetInfo.format_];
242             moduleInfo.sourceType = std::to_string(sourceType);
243             if (inputDesc != nullptr) {
244                 moduleInfo.deviceType = std::to_string(static_cast<int32_t>(inputDesc->deviceType_));
245             }
246             // update primary info for ec config to get later
247             primaryMicModuleInfo_.channels = std::to_string(targetInfo.channels_);
248             primaryMicModuleInfo_.rate = std::to_string(targetInfo.sampleRate_);
249             primaryMicModuleInfo_.format = AudioDefinitionPolicyUtils::enumToFormatStr[targetInfo.format_];
250         }
251     }
252 }
253 
UpdateStreamEcInfo(AudioModuleInfo & moduleInfo,SourceType sourceType)254 void AudioEcManager::UpdateStreamEcInfo(AudioModuleInfo &moduleInfo, SourceType sourceType)
255 {
256     if (sourceType != SOURCE_TYPE_VOICE_COMMUNICATION && sourceType != SOURCE_TYPE_VOICE_TRANSCRIPTION) {
257         AUDIO_INFO_LOG("sourceType: %{public}d not need ec data", sourceType);
258         return;
259     }
260 
261     std::vector<std::shared_ptr<AudioDeviceDescriptor>> outputDesc =
262         audioRouterCenter_.FetchOutputDevices(STREAM_USAGE_VOICE_COMMUNICATION, -1, "UpdateStreamEcInfo");
263     std::shared_ptr<AudioDeviceDescriptor> inputDesc =
264         audioRouterCenter_.FetchInputDevice(SOURCE_TYPE_VOICE_COMMUNICATION, -1);
265 
266     CHECK_AND_RETURN_LOG(inputDesc && !outputDesc.empty() && outputDesc.front(), "Device is nullptr");
267     UpdateAudioEcInfo(*inputDesc, *outputDesc.front());
268     UpdateModuleInfoForEc(moduleInfo);
269 }
270 
UpdateStreamMicRefInfo(AudioModuleInfo & moduleInfo,SourceType sourceType)271 void AudioEcManager::UpdateStreamMicRefInfo(AudioModuleInfo &moduleInfo, SourceType sourceType)
272 {
273     if (sourceType != SOURCE_TYPE_VOICE_COMMUNICATION && sourceType != SOURCE_TYPE_MIC) {
274         AUDIO_INFO_LOG("sourceType: %{public}d not need micref data", sourceType);
275         return;
276     }
277 
278     UpdateModuleInfoForMicRef(moduleInfo, sourceType);
279 }
280 
GetEcSamplingRate(const std::string & halName,std::shared_ptr<PipeStreamPropInfo> & outModuleInfo)281 std::string AudioEcManager::GetEcSamplingRate(const std::string &halName,
282     std::shared_ptr<PipeStreamPropInfo> &outModuleInfo)
283 {
284     if (halName == DP_CLASS) {
285         if (!dpSinkModuleInfo_.rate.empty()) {
286             AUDIO_INFO_LOG("use dp cust param");
287             return dpSinkModuleInfo_.rate;
288         }
289         return std::to_string(outModuleInfo->sampleRate_);
290     } else if (halName == USB_CLASS) {
291         if (!usbSinkModuleInfo_.rate.empty()) {
292             AUDIO_INFO_LOG("use arm usb cust param");
293             return usbSinkModuleInfo_.rate;
294         }
295         return std::to_string(outModuleInfo->sampleRate_);
296     } else {
297         return primaryMicModuleInfo_.rate;
298     }
299 }
300 
GetEcFormat(const std::string & halName,std::shared_ptr<PipeStreamPropInfo> & outModuleInfo)301 std::string AudioEcManager::GetEcFormat(const std::string &halName,
302     std::shared_ptr<PipeStreamPropInfo> &outModuleInfo)
303 {
304     if (halName == DP_CLASS) {
305         if (!dpSinkModuleInfo_.format.empty()) {
306             AUDIO_INFO_LOG("use dp cust param");
307             return dpSinkModuleInfo_.format;
308         }
309         return AudioDefinitionPolicyUtils::enumToFormatStr[outModuleInfo->format_];
310     } else if (halName == USB_CLASS) {
311         if (!usbSinkModuleInfo_.format.empty()) {
312             AUDIO_INFO_LOG("use arm usb cust param");
313             return usbSinkModuleInfo_.format;
314         }
315         return AudioDefinitionPolicyUtils::enumToFormatStr[outModuleInfo->format_];
316     } else {
317         return primaryMicModuleInfo_.format;
318     }
319 }
320 
GetEcChannels(const std::string & halName,std::shared_ptr<PipeStreamPropInfo> & outModuleInfo)321 std::string AudioEcManager::GetEcChannels(const std::string &halName,
322     std::shared_ptr<PipeStreamPropInfo> &outModuleInfo)
323 {
324     if (halName == DP_CLASS) {
325         if (!dpSinkModuleInfo_.channels.empty()) {
326             AUDIO_INFO_LOG("use dp cust param");
327             return dpSinkModuleInfo_.channels;
328         }
329         return std::to_string(outModuleInfo->channels_);
330     } else if (halName == USB_CLASS) {
331         if (!usbSinkModuleInfo_.channels.empty()) {
332             AUDIO_INFO_LOG("use arm usb cust param");
333             return usbSinkModuleInfo_.channels;
334         }
335         return std::to_string(outModuleInfo->channels_);
336     } else {
337         return std::to_string(HEADPHONE_CHANNEL_NUM);
338     }
339 }
340 
GetPipeNameByDeviceForEc(const std::string & role,const DeviceType deviceType)341 std::string AudioEcManager::GetPipeNameByDeviceForEc(const std::string &role, const DeviceType deviceType)
342 {
343     switch (deviceType) {
344         case DEVICE_TYPE_SPEAKER:
345             return PIPE_PRIMARY_OUTPUT;
346         case DEVICE_TYPE_WIRED_HEADSET:
347         case DEVICE_TYPE_USB_HEADSET:
348         case DEVICE_TYPE_BLUETOOTH_SCO:
349             if (role == ROLE_SOURCE) {
350                 return PIPE_PRIMARY_INPUT;
351             }
352             return PIPE_PRIMARY_OUTPUT;
353         case DEVICE_TYPE_MIC:
354             return PIPE_PRIMARY_INPUT;
355         case DEVICE_TYPE_USB_ARM_HEADSET:
356             if (role == ROLE_SOURCE) {
357                 return PIPE_USB_ARM_INPUT;
358             }
359             return PIPE_USB_ARM_OUTPUT;
360         case DEVICE_TYPE_DP:
361             return PIPE_DP_OUTPUT;
362         case DEVICE_TYPE_ACCESSORY:
363             return PIPE_ACCESSORY_INPUT;
364         default:
365             AUDIO_ERR_LOG("invalid device type %{public}d for role %{public}s", deviceType, role.c_str());
366             return PIPE_PRIMARY_OUTPUT;
367     }
368 }
369 
GetPipeInfoByDeviceTypeForEc(const std::string & role,const DeviceType deviceType,std::shared_ptr<AdapterPipeInfo> & pipeInfo)370 int32_t AudioEcManager::GetPipeInfoByDeviceTypeForEc(const std::string &role, const DeviceType deviceType,
371     std::shared_ptr<AdapterPipeInfo> &pipeInfo)
372 {
373     std::string portName;
374     if (role == ROLE_SOURCE) {
375         portName = AudioPolicyUtils::GetInstance().GetSourcePortName(deviceType);
376     } else {
377         portName = AudioPolicyUtils::GetInstance().GetSinkPortName(deviceType);
378     }
379     std::shared_ptr<PolicyAdapterInfo> info;
380     bool ret = audioConfigManager_.GetAdapterInfoByType(static_cast<AudioAdapterType>(
381         AudioPolicyUtils::portStrToEnum[portName]), info);
382     CHECK_AND_RETURN_RET_LOG(ret && info != nullptr, ERR_NOT_SUPPORTED,
383         "no adapter found for deviceType: %{public}d, portName: %{public}s", deviceType, portName.c_str());
384     std::string pipeName = GetPipeNameByDeviceForEc(role, deviceType);
385     pipeInfo = info->GetPipeInfoByName(pipeName);
386     if (pipeInfo == nullptr) {
387         AUDIO_ERR_LOG("no pipe info found for pipeName: %{public}s, deviceType: %{public}d, portName: %{public}s",
388             pipeName.c_str(), deviceType, portName.c_str());
389         return ERROR;
390     }
391     AUDIO_INFO_LOG("pipe name: %{public}s, moduleName: %{public}s found for device: %{public}d",
392         pipeInfo->name_.c_str(), pipeInfo->paProp_.moduleName_.c_str(), deviceType);
393     return SUCCESS;
394 }
395 
GetEcType(const DeviceType inputDevice,const DeviceType outputDevice)396 EcType AudioEcManager::GetEcType(const DeviceType inputDevice, const DeviceType outputDevice)
397 {
398     EcType ecType = EC_TYPE_NONE;
399     auto element = DEVICE_TO_EC_TYPE.find(std::make_pair(inputDevice, outputDevice));
400     if (element != DEVICE_TO_EC_TYPE.end()) {
401         ecType = element->second;
402     }
403     AUDIO_INFO_LOG("GetEcType ecType: %{public}d", ecType);
404     return ecType;
405 }
406 
UpdateAudioEcInfo(const AudioDeviceDescriptor & inputDevice,const AudioDeviceDescriptor & outputDevice)407 void AudioEcManager::UpdateAudioEcInfo(const AudioDeviceDescriptor &inputDevice,
408     const AudioDeviceDescriptor &outputDevice)
409 {
410     if (!isEcFeatureEnable_) {
411         AUDIO_INFO_LOG("UpdateModuleForEc ignore for feature not enable");
412         return;
413     }
414     std::lock_guard<std::mutex> lock(audioEcInfoMutex_);
415     if (audioEcInfo_.inputDevice.IsSameDeviceDesc(inputDevice) &&
416         audioEcInfo_.outputDevice.IsSameDeviceDesc(outputDevice)) {
417         AUDIO_INFO_LOG("UpdateModuleForEc abort, no device changed");
418         return;
419     }
420     audioEcInfo_.inputDevice = inputDevice;
421     audioEcInfo_.outputDevice = outputDevice;
422     audioEcInfo_.ecType = GetEcType(inputDevice.deviceType_, outputDevice.deviceType_);
423     audioEcInfo_.ecInputAdapter = GetHalNameForDevice(ROLE_SOURCE, inputDevice.deviceType_);
424     audioEcInfo_.ecOutputAdapter = GetHalNameForDevice(ROLE_SINK, outputDevice.deviceType_);
425     std::shared_ptr<AdapterPipeInfo> pipeInfo;
426     int32_t result = GetPipeInfoByDeviceTypeForEc(ROLE_SINK, outputDevice.deviceType_, pipeInfo);
427     CHECK_AND_RETURN_LOG(result == SUCCESS, "Ec stream not update for no pipe found");
428     audioEcInfo_.samplingRate = GetEcSamplingRate(audioEcInfo_.ecOutputAdapter, pipeInfo->streamPropInfos_.front());
429     audioEcInfo_.format = GetEcFormat(audioEcInfo_.ecOutputAdapter, pipeInfo->streamPropInfos_.front());
430     audioEcInfo_.channels = GetEcChannels(audioEcInfo_.ecOutputAdapter, pipeInfo->streamPropInfos_.front());
431     AUDIO_INFO_LOG("inputDevice: %{public}d, outputDevice: %{public}d, ecType: %{public}d, ecInputAdapter: %{public}s"
432         "ecOutputAdapter: %{public}s, samplingRate: %{public}s, format: %{public}s, channels: %{public}s",
433         audioEcInfo_.inputDevice.deviceType_, audioEcInfo_.outputDevice.deviceType_, audioEcInfo_.ecType,
434         audioEcInfo_.ecInputAdapter.c_str(), audioEcInfo_.ecOutputAdapter.c_str(), audioEcInfo_.samplingRate.c_str(),
435         audioEcInfo_.format.c_str(), audioEcInfo_.channels.c_str());
436 }
437 
UpdateModuleInfoForEc(AudioModuleInfo & moduleInfo)438 void AudioEcManager::UpdateModuleInfoForEc(AudioModuleInfo &moduleInfo)
439 {
440     std::lock_guard<std::mutex> lock(audioEcInfoMutex_);
441     moduleInfo.ecType = std::to_string(audioEcInfo_.ecType);
442     moduleInfo.ecAdapter = audioEcInfo_.ecOutputAdapter;
443     moduleInfo.ecSamplingRate = audioEcInfo_.samplingRate;
444     moduleInfo.ecFormat = audioEcInfo_.format;
445     moduleInfo.ecChannels = audioEcInfo_.channels;
446 }
447 
ShouldOpenMicRef(SourceType source)448 std::string AudioEcManager::ShouldOpenMicRef(SourceType source)
449 {
450     std::string shouldOpen = "0";
451     if (!isMicRefFeatureEnable_) {
452         AUDIO_INFO_LOG("isMicRefFeatureEnable_ is off");
453         return shouldOpen;
454     }
455 
456     std::shared_ptr<AudioDeviceDescriptor> inputDesc = audioRouterCenter_.FetchInputDevice(source, -1);
457     CHECK_AND_RETURN_RET_LOG(inputDesc != nullptr, shouldOpen, "inputDesc is nullptr");
458     auto iter = std::find(MIC_REF_DEVICES.begin(), MIC_REF_DEVICES.end(), inputDesc->deviceType_);
459     if ((source == SOURCE_TYPE_VOICE_COMMUNICATION && isMicRefVoipUpOn_ && iter != MIC_REF_DEVICES.end()) ||
460         (source == SOURCE_TYPE_MIC && isMicRefRecordOn_ && iter != MIC_REF_DEVICES.end())) {
461         shouldOpen = "1";
462     }
463 
464     AUDIO_INFO_LOG("source: %{public}d, voipUpMicOn: %{public}d, recordMicOn: %{public}d, device: %{public}d",
465         source, isMicRefVoipUpOn_, isMicRefRecordOn_, inputDesc->deviceType_);
466     return shouldOpen;
467 }
468 
UpdateModuleInfoForMicRef(AudioModuleInfo & moduleInfo,SourceType source)469 void AudioEcManager::UpdateModuleInfoForMicRef(AudioModuleInfo &moduleInfo, SourceType source)
470 {
471     moduleInfo.openMicRef = ShouldOpenMicRef(source);
472     moduleInfo.micRefRate = "48000";
473     moduleInfo.micRefFormat = "s16le";
474     moduleInfo.micRefChannels = "4";
475 }
476 
GetAudioEcInfo()477 AudioEcInfo AudioEcManager::GetAudioEcInfo()
478 {
479     std::lock_guard<std::mutex> lock(audioEcInfoMutex_);
480     return audioEcInfo_;
481 }
482 
ResetAudioEcInfo()483 void AudioEcManager::ResetAudioEcInfo()
484 {
485     std::lock_guard<std::mutex> lock(audioEcInfoMutex_);
486     audioEcInfo_.inputDevice.deviceType_ = DEVICE_TYPE_NONE;
487     audioEcInfo_.outputDevice.deviceType_ = DEVICE_TYPE_NONE;
488 }
489 
PresetArmIdleInput(const string & address)490 void AudioEcManager::PresetArmIdleInput(const string& address)
491 {
492     AUDIO_INFO_LOG("Entry. address=%{public}s", GetEncryptAddr(address).c_str());
493     std::list<AudioModuleInfo> moduleInfoList;
494     bool ret = audioConfigManager_.GetModuleListByType(ClassType::TYPE_USB, moduleInfoList);
495     CHECK_AND_RETURN_LOG(ret, "GetModuleListByType empty");
496     for (auto &moduleInfo : moduleInfoList) {
497         DeviceRole configRole = moduleInfo.role == "sink" ? OUTPUT_DEVICE : INPUT_DEVICE;
498         if (configRole != INPUT_DEVICE) {continue;}
499         UpdateArmModuleInfo(address, INPUT_DEVICE, moduleInfo);
500         if (isEcFeatureEnable_) {
501             usbSourceModuleInfo_ = moduleInfo;
502         }
503         audioConfigManager_.UpdateDynamicCapturerConfig(ClassType::TYPE_USB, moduleInfo);
504     }
505 }
506 
ActivateArmDevice(const string & address,const DeviceRole role)507 void AudioEcManager::ActivateArmDevice(const string& address, const DeviceRole role)
508 {
509     AUDIO_INFO_LOG("address=%{public}s, role=%{public}d", GetEncryptAddr(address).c_str(), role);
510     string &activeArmAddr = role == INPUT_DEVICE ? activeArmInputAddr_ : activeArmOutputAddr_;
511     CHECK_AND_RETURN_LOG(address != activeArmAddr, "usb device addr already active");
512     std::list<AudioModuleInfo> moduleInfoList;
513     bool ret = audioConfigManager_.GetModuleListByType(ClassType::TYPE_USB, moduleInfoList);
514     CHECK_AND_RETURN_LOG(ret, "GetModuleListByType empty");
515     for (auto &moduleInfo : moduleInfoList) {
516         DeviceRole configRole = moduleInfo.role == "sink" ? OUTPUT_DEVICE : INPUT_DEVICE;
517         if (configRole != role) {continue;}
518         AUDIO_INFO_LOG("[module_reload]: module[%{public}s], role[%{public}d]", moduleInfo.name.c_str(), role);
519         if (!(isEcFeatureEnable_ && role == INPUT_DEVICE) && audioIOHandleMap_.CheckIOHandleExist(moduleInfo.name)) {
520             audioIOHandleMap_.MuteDefaultSinkPort(audioActiveDevice_.GetCurrentOutputDeviceNetworkId(),
521                 AudioPolicyUtils::GetInstance().GetSinkPortName(audioActiveDevice_.GetCurrentOutputDeviceType()));
522             audioIOHandleMap_.ClosePortAndEraseIOHandle(moduleInfo.name);
523         }
524         UpdateArmModuleInfo(address, role, moduleInfo);
525         if (isEcFeatureEnable_) {
526             if (role == OUTPUT_DEVICE) {
527                 int32_t ret = audioIOHandleMap_.OpenPortAndInsertIOHandle(moduleInfo.name, moduleInfo);
528                 CHECK_AND_RETURN_LOG(ret == SUCCESS,
529                     "Load usb %{public}s failed %{public}d", moduleInfo.role.c_str(), ret);
530                 usbSinkModuleInfo_ = moduleInfo;
531             } else {
532                 AUDIO_INFO_LOG("just save arm usb source module info, rate=%{public}s", moduleInfo.rate.c_str());
533                 usbSourceModuleInfo_ = moduleInfo;
534             }
535         } else {
536             int32_t ret = audioIOHandleMap_.OpenPortAndInsertIOHandle(moduleInfo.name, moduleInfo);
537             CHECK_AND_RETURN_LOG(ret == SUCCESS,
538                 "Load usb %{public}s failed %{public}d", moduleInfo.role.c_str(), ret);
539         }
540     }
541     activeArmAddr = address;
542 }
543 
CloseUsbArmDevice(const AudioDeviceDescriptor & device)544 void AudioEcManager::CloseUsbArmDevice(const AudioDeviceDescriptor &device)
545 {
546     AUDIO_INFO_LOG("address=%{public}s, role=%{public}d",
547         GetEncryptAddr(device.macAddress_).c_str(), device.deviceRole_);
548     string &activeArmAddr = device.deviceRole_ == INPUT_DEVICE ? activeArmInputAddr_ : activeArmOutputAddr_;
549     CHECK_AND_RETURN_LOG(device.macAddress_ == activeArmAddr, "usb device addr not match");
550     std::list<AudioModuleInfo> moduleInfoList;
551     bool ret = audioConfigManager_.GetModuleListByType(ClassType::TYPE_USB, moduleInfoList);
552     CHECK_AND_RETURN_LOG(ret, "GetModuleListByType Failed");
553     for (auto &moduleInfo : moduleInfoList) {
554         DeviceRole configRole = moduleInfo.role == "sink" ? OUTPUT_DEVICE : INPUT_DEVICE;
555         if (configRole != device.deviceRole_) {continue;}
556         if (audioIOHandleMap_.CheckIOHandleExist(moduleInfo.name)) {
557             audioIOHandleMap_.ClosePortAndEraseIOHandle(moduleInfo.name);
558         }
559     }
560     activeArmAddr = "";
561 }
562 
UpdateArmModuleInfo(const string & address,const DeviceRole role,AudioModuleInfo & moduleInfo)563 void AudioEcManager::UpdateArmModuleInfo(const string& address, const DeviceRole role, AudioModuleInfo& moduleInfo)
564 {
565     string condition = string("address=") + address + " role=" + to_string(role);
566     string deviceInfo = AudioServerProxy::GetInstance().GetAudioParameterProxy(LOCAL_NETWORK_ID, USB_DEVICE,
567         condition);
568     AUDIO_INFO_LOG("device info from usb hal is %{public}s", deviceInfo.c_str());
569     if (!deviceInfo.empty()) {
570         GetUsbModuleInfo(deviceInfo, moduleInfo);
571         if (isEcFeatureEnable_) {
572             uint32_t rateValue = 0;
573             uint32_t channelValue = 0;
574             CHECK_AND_RETURN_LOG(StringConverter(moduleInfo.rate, rateValue),
575                 "convert invalid moduleInfo.rate: %{public}s", moduleInfo.rate.c_str());
576             CHECK_AND_RETURN_LOG(StringConverter(moduleInfo.channels, channelValue),
577                 "convert invalid moduleInfo.channels: %{public}s", moduleInfo.channels.c_str());
578             uint32_t bufferSize = rateValue * channelValue *
579                 AudioPolicyUtils::GetInstance().PcmFormatToBytes(formatStrToEnum[moduleInfo.format]) *
580                 RENDER_FRAME_INTERVAL_IN_SECONDS;
581             moduleInfo.bufferSize = std::to_string(bufferSize);
582             AUDIO_INFO_LOG("update arm usb buffer size: %{public}s", moduleInfo.bufferSize.c_str());
583         }
584     }
585 }
586 
GetTargetSourceTypeAndMatchingFlag(SourceType source,SourceType & targetSource,bool & useMatchingPropInfo)587 void AudioEcManager::GetTargetSourceTypeAndMatchingFlag(SourceType source,
588     SourceType &targetSource, bool &useMatchingPropInfo)
589 {
590     switch (source) {
591         case SOURCE_TYPE_VOICE_RECOGNITION:
592             targetSource = SOURCE_TYPE_VOICE_RECOGNITION;
593             useMatchingPropInfo = true;
594             break;
595         case SOURCE_TYPE_VOICE_COMMUNICATION:
596         case SOURCE_TYPE_VOICE_TRANSCRIPTION:
597             targetSource = SOURCE_TYPE_VOICE_COMMUNICATION;
598             useMatchingPropInfo = isEcFeatureEnable_ ? false : true;
599             break;
600         case SOURCE_TYPE_VOICE_CALL:
601             targetSource = SOURCE_TYPE_VOICE_CALL;
602             break;
603         case SOURCE_TYPE_UNPROCESSED:
604             targetSource = SOURCE_TYPE_UNPROCESSED;
605             useMatchingPropInfo = true;
606             break;
607         case SOURCE_TYPE_LIVE:
608             targetSource = SOURCE_TYPE_LIVE;
609             break;
610         default:
611             targetSource = SOURCE_TYPE_MIC;
612             break;
613     }
614 }
615 
ReloadSourceForSession(SessionInfo sessionInfo)616 void AudioEcManager::ReloadSourceForSession(SessionInfo sessionInfo)
617 {
618     AUDIO_INFO_LOG("reload session for source: %{public}d", sessionInfo.sourceType);
619 
620     PipeStreamPropInfo targetInfo;
621     SourceType targetSource = sessionInfo.sourceType;
622     int32_t res = FetchTargetInfoForSessionAdd(sessionInfo, targetInfo, targetSource);
623     CHECK_AND_RETURN_LOG(res == SUCCESS, "fetch target source info error");
624 
625     ReloadNormalSource(sessionInfo, targetInfo, targetSource);
626 
627     audioActiveDevice_.UpdateActiveDeviceRoute(audioActiveDevice_.GetCurrentInputDeviceType(),
628         DeviceFlag::INPUT_DEVICES_FLAG, audioActiveDevice_.GetCurrentInputDevice().deviceName_,
629         audioActiveDevice_.GetCurrentInputDevice().networkId_);
630 }
631 
FetchTargetInfoForSessionAdd(const SessionInfo sessionInfo,PipeStreamPropInfo & targetInfo,SourceType & targetSourceType)632 int32_t AudioEcManager::FetchTargetInfoForSessionAdd(const SessionInfo sessionInfo, PipeStreamPropInfo &targetInfo,
633     SourceType &targetSourceType)
634 {
635     std::shared_ptr<AdapterPipeInfo> pipeInfoPtr = nullptr;
636     std::shared_ptr<PolicyAdapterInfo> adapterInfo = nullptr;
637     bool ret = audioConfigManager_.GetAdapterInfoByType(AudioAdapterType::TYPE_PRIMARY, adapterInfo);
638     if (ret) {
639         pipeInfoPtr = adapterInfo->GetPipeInfoByName(PIPE_PRIMARY_INPUT);
640     }
641     CHECK_AND_RETURN_RET_LOG(pipeInfoPtr != nullptr, ERROR, "pipeInfoPtr is null");
642 
643     const auto &streamPropInfoList = pipeInfoPtr->streamPropInfos_;
644 
645     if (streamPropInfoList.empty()) {
646         AUDIO_ERR_LOG("supportedRate or supportedChannels is empty");
647         return ERROR;
648     }
649 
650     // use first profile as default
651     std::shared_ptr<PipeStreamPropInfo> targetStreamPropInfo = *streamPropInfoList.begin();
652     bool useMatchingPropInfo = false;
653     GetTargetSourceTypeAndMatchingFlag(sessionInfo.sourceType, targetSourceType, useMatchingPropInfo);
654 
655     if (useMatchingPropInfo) {
656         for (const auto &streamPropInfo : streamPropInfoList) {
657             if (sessionInfo.channels == streamPropInfo->channels_ &&
658                 sessionInfo.rate == streamPropInfo->sampleRate_) {
659                 targetStreamPropInfo = streamPropInfo;
660                 break;
661             }
662         }
663     }
664     targetInfo = *targetStreamPropInfo;
665 
666     if (isEcFeatureEnable_) {
667         std::shared_ptr<AudioDeviceDescriptor> inputDesc = audioRouterCenter_.FetchInputDevice(targetSourceType, -1);
668         if (inputDesc != nullptr && inputDesc->deviceType_ != DEVICE_TYPE_MIC &&
669             targetInfo.channels_ == PC_MIC_CHANNEL_NUM) {
670             // only built-in mic can use 4 channel, update later by using xml to describe
671             targetInfo.channels_ = static_cast<AudioChannel>(HEADPHONE_CHANNEL_NUM);
672             targetInfo.channelLayout_ = CH_LAYOUT_STEREO;
673         }
674     }
675 
676 #ifndef IS_EMULATOR
677     // need change to use profile for all devices later
678     if (primaryMicModuleInfo_.OpenMicSpeaker == "1") {
679         uint32_t sampleFormatBits = AudioPolicyUtils::GetInstance().PcmFormatToBytes(targetInfo.format_);
680         targetInfo.bufferSize_ = BUFFER_CALC_20MS * targetInfo.sampleRate_ / static_cast<uint32_t>(MS_PER_S)
681             * targetInfo.channels_ * sampleFormatBits;
682     }
683 #endif
684 
685     return SUCCESS;
686 }
687 
SetDpSinkModuleInfo(const AudioModuleInfo & moduleInfo)688 void AudioEcManager::SetDpSinkModuleInfo(const AudioModuleInfo &moduleInfo)
689 {
690     dpSinkModuleInfo_ = moduleInfo;
691 }
692 
SetPrimaryMicModuleInfo(const AudioModuleInfo & moduleInfo)693 void AudioEcManager::SetPrimaryMicModuleInfo(const AudioModuleInfo &moduleInfo)
694 {
695     primaryMicModuleInfo_ = moduleInfo;
696 }
697 
GetSourceOpened()698 SourceType AudioEcManager::GetSourceOpened()
699 {
700     return normalSourceOpened_;
701 }
702 
GetEcFeatureEnable()703 bool AudioEcManager::GetEcFeatureEnable()
704 {
705     return isEcFeatureEnable_;
706 }
707 
GetMicRefFeatureEnable()708 bool AudioEcManager::GetMicRefFeatureEnable()
709 {
710     return isMicRefFeatureEnable_;
711 }
712 
UpdateStreamEcAndMicRefInfo(AudioModuleInfo & moduleInfo,SourceType sourceType)713 void AudioEcManager::UpdateStreamEcAndMicRefInfo(AudioModuleInfo &moduleInfo, SourceType sourceType)
714 {
715     UpdateStreamEcInfo(moduleInfo, sourceType);
716     UpdateStreamMicRefInfo(moduleInfo, sourceType);
717 }
718 
GetHalNameForDevice(const std::string & role,const DeviceType deviceType)719 std::string AudioEcManager::GetHalNameForDevice(const std::string &role, const DeviceType deviceType)
720 {
721     std::string halName = "";
722     std::string portName;
723     if (role == ROLE_SOURCE) {
724         portName = AudioPolicyUtils::GetInstance().GetSourcePortName(deviceType);
725     } else {
726         portName = AudioPolicyUtils::GetInstance().GetSinkPortName(deviceType);
727     }
728     std::shared_ptr<PolicyAdapterInfo> info;
729     bool ret = audioConfigManager_.GetAdapterInfoByType(static_cast<AudioAdapterType>(
730         AudioPolicyUtils::portStrToEnum[portName]), info);
731     if (ret) {
732         halName = info->adapterName;
733     }
734     AUDIO_INFO_LOG("role: %{public}s, device: %{public}d, halName: %{public}s",
735         role.c_str(), deviceType, halName.c_str());
736     return halName;
737 }
738 
SetOpenedNormalSource(SourceType sourceType)739 void AudioEcManager::SetOpenedNormalSource(SourceType sourceType)
740 {
741     normalSourceOpened_ = sourceType;
742 }
743 
PrepareNormalSource(AudioModuleInfo & moduleInfo,std::shared_ptr<AudioStreamDescriptor> & streamDesc)744 void AudioEcManager::PrepareNormalSource(AudioModuleInfo &moduleInfo,
745     std::shared_ptr<AudioStreamDescriptor> &streamDesc)
746 {
747     SourceType sourceType = streamDesc->capturerInfo_.sourceType;
748     AUDIO_INFO_LOG("prepare normal source for source type: %{public}d", sourceType);
749     UpdateEnhanceEffectState(sourceType);
750     UpdateStreamEcAndMicRefInfo(moduleInfo, sourceType);
751     SetOpenedNormalSource(sourceType);
752     SetOpenedNormalSourceSessionId(streamDesc->sessionId_);
753 }
754 
SetOpenedNormalSourceSessionId(uint64_t sessionId)755 void AudioEcManager::SetOpenedNormalSourceSessionId(uint64_t sessionId)
756 {
757     AUDIO_INFO_LOG("set normal source sessionId: %{public}" PRIu64, sessionId);
758     sessionIdUsedToOpenSource_ = sessionId;
759 }
760 
GetOpenedNormalSourceSessionId()761 uint64_t AudioEcManager::GetOpenedNormalSourceSessionId()
762 {
763     return sessionIdUsedToOpenSource_;
764 }
765 
ReloadNormalSource(SessionInfo & sessionInfo,PipeStreamPropInfo & targetInfo,SourceType targetSource)766 int32_t AudioEcManager::ReloadNormalSource(SessionInfo &sessionInfo,
767     PipeStreamPropInfo &targetInfo, SourceType targetSource)
768 {
769     std::shared_ptr<AudioPipeInfo> pipeInfo =
770         AudioPipeManager::GetPipeManager()->GetNormalSourceInfo(isEcFeatureEnable_);
771     CHECK_AND_RETURN_RET_LOG(pipeInfo != nullptr, ERROR, "Get normal source info failed");
772 
773     AudioModuleInfo moduleInfo;
774     UpdateEnhanceEffectState(targetSource);
775     UpdateStreamCommonInfo(moduleInfo, targetInfo, targetSource);
776     UpdateStreamEcInfo(moduleInfo, targetSource);
777     UpdateStreamMicRefInfo(moduleInfo, targetSource);
778 
779     AUDIO_INFO_LOG("rate: %{public}s, channels: %{public}s, bufferSize: %{public}s format: %{public}s, "
780         "sourceType: %{public}s",
781         moduleInfo.rate.c_str(), moduleInfo.channels.c_str(), moduleInfo.bufferSize.c_str(),
782         moduleInfo.format.c_str(), moduleInfo.sourceType.c_str());
783 
784     audioIOHandleMap_.ReloadPortAndUpdateIOHandle(pipeInfo, moduleInfo);
785     audioPolicyManager_.SetDeviceActive(audioActiveDevice_.GetCurrentInputDeviceType(), moduleInfo.name,
786         true, INPUT_DEVICES_FLAG);
787 
788     normalSourceOpened_ = targetSource;
789     return SUCCESS;
790 }
791 }
792 }
793