1 /*
2 * Copyright (c) 2024 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 "AudioEffectChainAdapter"
17 #endif
18
19 #include "audio_effect_chain_adapter.h"
20 #include "audio_effect_chain_manager.h"
21 #include "audio_effect.h"
22 #include "audio_errors.h"
23 #include "audio_effect_log.h"
24 #include "securec.h"
25
26 using namespace OHOS::AudioStandard;
27
28 static std::map<AudioChannelSet, pa_channel_position> chSetToPaPositionMap = {
29 {FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_LEFT},
30 {FRONT_RIGHT, PA_CHANNEL_POSITION_FRONT_RIGHT},
31 {FRONT_CENTER, PA_CHANNEL_POSITION_FRONT_CENTER},
32 {LOW_FREQUENCY, PA_CHANNEL_POSITION_LFE},
33 {SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_LEFT},
34 {SIDE_RIGHT, PA_CHANNEL_POSITION_SIDE_RIGHT},
35 {BACK_LEFT, PA_CHANNEL_POSITION_REAR_LEFT},
36 {BACK_RIGHT, PA_CHANNEL_POSITION_REAR_RIGHT},
37 {FRONT_LEFT_OF_CENTER, PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER},
38 {FRONT_RIGHT_OF_CENTER, PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER},
39 {BACK_CENTER, PA_CHANNEL_POSITION_REAR_CENTER},
40 {TOP_CENTER, PA_CHANNEL_POSITION_TOP_CENTER},
41 {TOP_FRONT_LEFT, PA_CHANNEL_POSITION_TOP_FRONT_LEFT},
42 {TOP_FRONT_CENTER, PA_CHANNEL_POSITION_TOP_FRONT_CENTER},
43 {TOP_FRONT_RIGHT, PA_CHANNEL_POSITION_TOP_FRONT_RIGHT},
44 {TOP_BACK_LEFT, PA_CHANNEL_POSITION_TOP_REAR_LEFT},
45 {TOP_BACK_CENTER, PA_CHANNEL_POSITION_TOP_REAR_CENTER},
46 {TOP_BACK_RIGHT, PA_CHANNEL_POSITION_TOP_REAR_RIGHT},
47 /** Channel layout positions below do not have precise mapped pulseaudio positions */
48 {STEREO_LEFT, PA_CHANNEL_POSITION_FRONT_LEFT},
49 {STEREO_RIGHT, PA_CHANNEL_POSITION_FRONT_RIGHT},
50 {WIDE_LEFT, PA_CHANNEL_POSITION_FRONT_LEFT},
51 {WIDE_RIGHT, PA_CHANNEL_POSITION_FRONT_RIGHT},
52 {SURROUND_DIRECT_LEFT, PA_CHANNEL_POSITION_SIDE_LEFT},
53 {SURROUND_DIRECT_RIGHT, PA_CHANNEL_POSITION_SIDE_LEFT},
54 {BOTTOM_FRONT_CENTER, PA_CHANNEL_POSITION_FRONT_CENTER},
55 {BOTTOM_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_LEFT},
56 {BOTTOM_FRONT_RIGHT, PA_CHANNEL_POSITION_FRONT_RIGHT},
57 {TOP_SIDE_LEFT, PA_CHANNEL_POSITION_TOP_REAR_LEFT},
58 {TOP_SIDE_RIGHT, PA_CHANNEL_POSITION_TOP_REAR_RIGHT},
59 {LOW_FREQUENCY_2, PA_CHANNEL_POSITION_LFE},
60 };
61
EffectChainManagerProcess(char * sceneType,BufferAttr * bufferAttr)62 int32_t EffectChainManagerProcess(char *sceneType, BufferAttr *bufferAttr)
63 {
64 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
65 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager");
66 std::string sceneTypeString = "";
67 if (sceneType) {
68 sceneTypeString = sceneType;
69 }
70 auto eBufferAttr = std::make_unique<EffectBufferAttr>(bufferAttr->bufIn, bufferAttr->bufOut, bufferAttr->numChanIn,
71 bufferAttr->frameLen);
72 if (audioEffectChainManager->ApplyAudioEffectChain(sceneTypeString, eBufferAttr) != SUCCESS) {
73 return ERROR;
74 }
75 return SUCCESS;
76 }
77
EffectChainManagerExist(const char * sceneType,const char * effectMode,const char * spatializationEnabled)78 bool EffectChainManagerExist(const char *sceneType, const char *effectMode, const char *spatializationEnabled)
79 {
80 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
81 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, false, "null audioEffectChainManager");
82 std::string sceneTypeString = "";
83 if (sceneType) {
84 sceneTypeString = sceneType;
85 }
86 std::string effectModeString = "";
87 if (effectMode) {
88 effectModeString = effectMode;
89 }
90 std::string spatializationEnabledString = "";
91 if (spatializationEnabled) {
92 spatializationEnabledString = spatializationEnabled;
93 }
94 return audioEffectChainManager->ExistAudioEffectChain(sceneTypeString, effectModeString,
95 spatializationEnabledString);
96 }
97
EffectChainManagerCreateCb(const char * sceneType,const char * sessionID)98 int32_t EffectChainManagerCreateCb(const char *sceneType, const char *sessionID)
99 {
100 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
101 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager");
102 std::string sceneTypeString = "";
103 std::string sessionIDString = "";
104 if (sceneType) {
105 sceneTypeString = sceneType;
106 }
107 if (sessionID) {
108 sessionIDString = sessionID;
109 }
110 if (!audioEffectChainManager->CheckAndAddSessionID(sessionIDString)) {
111 return SUCCESS;
112 }
113 audioEffectChainManager->UpdateSceneTypeList(sceneTypeString, ADD_SCENE_TYPE);
114 bool curSpatializationEnabled = audioEffectChainManager->GetCurSpatializationEnabled();
115 std::string curDeviceType = audioEffectChainManager->GetDeviceTypeName();
116 if (audioEffectChainManager->GetOffloadEnabled() ||
117 ((curDeviceType == "DEVICE_TYPE_BLUETOOTH_A2DP") && !curSpatializationEnabled)) {
118 return SUCCESS;
119 }
120 if (audioEffectChainManager->CreateAudioEffectChainDynamic(sceneTypeString) != SUCCESS) {
121 AUDIO_ERR_LOG("create effect chain fail");
122 return ERROR;
123 }
124 AUDIO_INFO_LOG("Create Audio Effect Chain Success, sessionID is %{public}s, sceneType is %{public}s",
125 sessionIDString.c_str(), sceneTypeString.c_str());
126 return SUCCESS;
127 }
128
EffectChainManagerReleaseCb(const char * sceneType,const char * sessionID)129 int32_t EffectChainManagerReleaseCb(const char *sceneType, const char *sessionID)
130 {
131 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
132 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager");
133 std::string sceneTypeString = "";
134 std::string sessionIDString = "";
135 if (sceneType) {
136 sceneTypeString = sceneType;
137 }
138 if (sessionID) {
139 sessionIDString = sessionID;
140 }
141 if (!audioEffectChainManager->CheckAndRemoveSessionID(sessionIDString)) {
142 return SUCCESS;
143 }
144 audioEffectChainManager->UpdateSceneTypeList(sceneTypeString, REMOVE_SCENE_TYPE);
145 bool curSpatializationEnabled = audioEffectChainManager->GetCurSpatializationEnabled();
146 std::string curDeviceType = audioEffectChainManager->GetDeviceTypeName();
147 if (audioEffectChainManager->GetOffloadEnabled() ||
148 ((curDeviceType == "DEVICE_TYPE_BLUETOOTH_A2DP") && !curSpatializationEnabled)) {
149 return SUCCESS;
150 }
151 if (audioEffectChainManager->ReleaseAudioEffectChainDynamic(sceneTypeString) != SUCCESS) {
152 AUDIO_ERR_LOG("release effect chain fail");
153 return ERROR;
154 }
155 AUDIO_INFO_LOG("Release Audio Effect Chain Success, sessionID is %{public}s, sceneType is %{public}s",
156 sessionIDString.c_str(), sceneTypeString.c_str());
157 return SUCCESS;
158 }
159
EffectChainManagerMultichannelUpdate(const char * sceneType)160 int32_t EffectChainManagerMultichannelUpdate(const char *sceneType)
161 {
162 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
163 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager");
164 std::string sceneTypeString = "";
165 if (sceneType != nullptr && strlen(sceneType)) {
166 sceneTypeString = sceneType;
167 } else {
168 AUDIO_ERR_LOG("Scenetype is null.");
169 return ERROR;
170 }
171 if (audioEffectChainManager->UpdateMultichannelConfig(sceneTypeString) != SUCCESS) {
172 return ERROR;
173 }
174 return SUCCESS;
175 }
176
EffectChainManagerVolumeUpdate(const char * sessionID)177 int32_t EffectChainManagerVolumeUpdate(const char *sessionID)
178 {
179 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
180 std::shared_ptr<AudioEffectVolume> audioEffectVolume = AudioEffectVolume::GetInstance();
181 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager");
182 if (audioEffectChainManager->EffectVolumeUpdate(audioEffectVolume) != SUCCESS) {
183 return ERROR;
184 }
185 return SUCCESS;
186 }
187
ConvertChLayoutToPaChMap(const uint64_t channelLayout,pa_channel_map * paMap)188 uint32_t ConvertChLayoutToPaChMap(const uint64_t channelLayout, pa_channel_map *paMap)
189 {
190 if (channelLayout == CH_LAYOUT_MONO) {
191 pa_channel_map_init_mono(paMap);
192 return AudioChannel::MONO;
193 }
194 uint32_t channelNum = 0;
195 uint64_t mode = (channelLayout & CH_MODE_MASK) >> CH_MODE_OFFSET;
196 switch (mode) {
197 case 0: {
198 for (auto bit = chSetToPaPositionMap.begin(); bit != chSetToPaPositionMap.end(); ++bit) {
199 if ((channelLayout & (bit->first)) != 0) {
200 paMap->map[channelNum++] = bit->second;
201 }
202 }
203 break;
204 }
205 case 1: {
206 uint64_t order = (channelLayout & CH_HOA_ORDNUM_MASK) >> CH_HOA_ORDNUM_OFFSET;
207 channelNum = (order + 1) * (order + 1);
208 for (uint32_t i = 0; i < channelNum; ++i) {
209 paMap->map[i] = chSetToPaPositionMap[FRONT_LEFT];
210 }
211 break;
212 }
213 default:
214 channelNum = 0;
215 break;
216 }
217 return channelNum;
218 }
219
EffectChainManagerInitCb(const char * sceneType)220 int32_t EffectChainManagerInitCb(const char *sceneType)
221 {
222 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
223 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager");
224 std::string sceneTypeString = "";
225 if (sceneType) {
226 sceneTypeString = sceneType;
227 }
228 if (audioEffectChainManager->InitAudioEffectChainDynamic(sceneTypeString) != SUCCESS) {
229 return ERROR;
230 }
231 return SUCCESS;
232 }
233
EffectChainManagerCheckEffectOffload()234 bool EffectChainManagerCheckEffectOffload()
235 {
236 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
237 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, false, "null audioEffectChainManager");
238 return audioEffectChainManager->GetOffloadEnabled();
239 }
240
EffectChainManagerAddSessionInfo(const char * sceneType,const char * sessionID,SessionInfoPack pack)241 int32_t EffectChainManagerAddSessionInfo(const char *sceneType, const char *sessionID, SessionInfoPack pack)
242 {
243 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
244 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager");
245
246 uint64_t channelLayoutNum = 0;
247 int32_t streamUsage = 0;
248 int32_t systemVolumeType = 0;
249 std::string sceneTypeString = "";
250 std::string sessionIDString = "";
251 std::string sceneModeString = "";
252 std::string spatializationEnabledString = "";
253 if (sceneType && pack.channelLayout && sessionID && pack.sceneMode &&
254 pack.spatializationEnabled && pack.streamUsage) {
255 sceneTypeString = sceneType;
256 channelLayoutNum = std::strtoull(pack.channelLayout, nullptr, BASE_TEN);
257 sessionIDString = sessionID;
258 sceneModeString = pack.sceneMode;
259 spatializationEnabledString = pack.spatializationEnabled;
260 streamUsage = static_cast<int32_t>(std::strtol(pack.streamUsage, nullptr, BASE_TEN));
261 systemVolumeType = static_cast<int32_t>(std::strtol(pack.systemVolumeType, nullptr, BASE_TEN));
262 } else {
263 AUDIO_ERR_LOG("map input parameters missing.");
264 return ERROR;
265 }
266
267 SessionEffectInfo info;
268 info.sceneMode = sceneModeString;
269 info.sceneType = sceneTypeString;
270 info.channels = pack.channels;
271 info.channelLayout = channelLayoutNum;
272 info.spatializationEnabled = spatializationEnabledString;
273 info.streamUsage = streamUsage;
274 info.systemVolumeType = systemVolumeType;
275 return audioEffectChainManager->SessionInfoMapAdd(sessionIDString, info);
276 }
277
EffectChainManagerDeleteSessionInfo(const char * sceneType,const char * sessionID)278 int32_t EffectChainManagerDeleteSessionInfo(const char *sceneType, const char *sessionID)
279 {
280 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
281 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager");
282
283 std::string sceneTypeString = "";
284 std::string sessionIDString = "";
285 if (sceneType && sessionID) {
286 sceneTypeString = sceneType;
287 sessionIDString = sessionID;
288 } else {
289 AUDIO_ERR_LOG("map unlink parameters missing.");
290 return ERROR;
291 }
292
293 return audioEffectChainManager->SessionInfoMapDelete(sceneTypeString, sessionIDString);
294 }
295
EffectChainManagerReturnEffectChannelInfo(const char * sceneType,uint32_t * channels,uint64_t * channelLayout)296 int32_t EffectChainManagerReturnEffectChannelInfo(const char *sceneType, uint32_t *channels, uint64_t *channelLayout)
297 {
298 if (sceneType == nullptr || channels == nullptr || channelLayout == nullptr) {
299 return ERROR;
300 }
301 std::string sceneTypeString = sceneType;
302 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
303 uint32_t &chans = *channels;
304 uint64_t &chLayout = *channelLayout;
305 return audioEffectChainManager->ReturnEffectChannelInfo(sceneTypeString, chans, chLayout);
306 }
307
EffectChainManagerReturnMultiChannelInfo(uint32_t * channels,uint64_t * channelLayout)308 int32_t EffectChainManagerReturnMultiChannelInfo(uint32_t *channels, uint64_t *channelLayout)
309 {
310 if (channels == nullptr || channelLayout == nullptr) {
311 return ERROR;
312 }
313 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
314 return audioEffectChainManager->ReturnMultiChannelInfo(channels, channelLayout);
315 }
316
EffectChainManagerGetSpatializationEnabled()317 bool EffectChainManagerGetSpatializationEnabled()
318 {
319 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
320 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, false, "null audioEffectChainManager");
321 return audioEffectChainManager->GetCurSpatializationEnabled();
322 }
323
EffectChainManagerFlush(void)324 void EffectChainManagerFlush(void)
325 {
326 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
327 CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "null audioEffectChainManager");
328 return audioEffectChainManager->ResetEffectBuffer();
329 }
330
EffectChainManagerEffectUpdate()331 void EffectChainManagerEffectUpdate()
332 {
333 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
334 CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "null audioEffectChainManager");
335 audioEffectChainManager->UpdateDefaultAudioEffect();
336 }
337
EffectChainManagerStreamUsageUpdate()338 void EffectChainManagerStreamUsageUpdate()
339 {
340 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
341 CHECK_AND_RETURN_LOG(audioEffectChainManager != nullptr, "null audioEffectChainManager");
342 audioEffectChainManager->UpdateStreamUsage();
343 }
344
EffectChainManagerSceneCheck(const char * sinkSceneType,const char * sceneType)345 bool EffectChainManagerSceneCheck(const char *sinkSceneType, const char *sceneType)
346 {
347 if (sceneType == nullptr || sinkSceneType == nullptr) {
348 return false;
349 }
350 AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance();
351 CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, false, "null audioEffectChainManager");
352 std::string sceneTypeString = sceneType;
353 std::string sinkSceneTypeString = sinkSceneType;
354 return audioEffectChainManager->CheckSceneTypeMatch(sinkSceneTypeString, sceneTypeString);
355 }
356