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