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