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