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