• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-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 "AudioEffectChain"
17 #endif
18 
19 #include "audio_effect_chain.h"
20 #include "audio_effect.h"
21 #include "audio_errors.h"
22 #include "audio_effect_log.h"
23 #include "audio_dump_pcm.h"
24 #include "securec.h"
25 #include "media_monitor_manager.h"
26 #include "audio_effect_map.h"
27 #include "audio_utils.h"
28 
29 namespace OHOS {
30 namespace AudioStandard {
31 
32 static constexpr uint32_t DEFAULT_SAMPLE_RATE = 48000;
33 static constexpr uint32_t MAX_UINT_VOLUME = 65535;
34 static constexpr uint32_t DEFAULT_NUM_CHANNEL = STEREO;
35 static constexpr uint64_t DEFAULT_NUM_CHANNELLAYOUT = CH_LAYOUT_STEREO;
36 static constexpr int32_t CROSS_FADE_FRAME_COUNT = 5;
37 static constexpr int32_t DEFAULT_FRAME_LEN = 960;
38 static constexpr int32_t MAX_CHANNEL_NUM = 16;
39 
40 #ifdef SENSOR_ENABLE
AudioEffectChain(std::string scene,std::shared_ptr<HeadTracker> headTracker)41 AudioEffectChain::AudioEffectChain(std::string scene, std::shared_ptr<HeadTracker> headTracker)
42     : effectBuffer_(MAX_CHANNEL_NUM * DEFAULT_FRAME_LEN)
43 {
44     const std::unordered_map<AudioEffectMode, std::string> &audioSupportedSceneModes = GetAudioSupportedSceneModes();
45 
46     sceneType_ = scene;
47     effectMode_ = audioSupportedSceneModes.find(EFFECT_DEFAULT)->second;
48     audioBufIn_.frameLength = 0;
49     audioBufOut_.frameLength = 0;
50     ioBufferConfig_.inputCfg.samplingRate = DEFAULT_SAMPLE_RATE;
51     ioBufferConfig_.inputCfg.channels = DEFAULT_NUM_CHANNEL;
52     ioBufferConfig_.inputCfg.format = DATA_FORMAT_F32;
53     ioBufferConfig_.inputCfg.channelLayout = DEFAULT_NUM_CHANNELLAYOUT;
54     ioBufferConfig_.outputCfg.samplingRate = DEFAULT_SAMPLE_RATE;
55     ioBufferConfig_.outputCfg.channels = DEFAULT_NUM_CHANNEL;
56     ioBufferConfig_.outputCfg.format = DATA_FORMAT_F32;
57     ioBufferConfig_.outputCfg.channelLayout = DEFAULT_NUM_CHANNELLAYOUT;
58     headTracker_ = headTracker;
59     dumpNameIn_ = "dump_effect_in_" + scene + "_"
60         + std::to_string(ioBufferConfig_.inputCfg.samplingRate) + "_"
61         + std::to_string(ioBufferConfig_.inputCfg.channels) + "_4_"
62         + GetTime() + ".pcm";
63     dumpNameOut_ = "dump_effect_out_" + scene + "_"
64         + std::to_string(ioBufferConfig_.outputCfg.samplingRate) + "_"
65         + std::to_string(ioBufferConfig_.outputCfg.channels) + "_4_"
66         + GetTime() + ".pcm";
67     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpNameIn_, &dumpFileInput_);
68     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpNameOut_, &dumpFileOutput_);
69 }
70 #else
AudioEffectChain(std::string scene)71 AudioEffectChain::AudioEffectChain(std::string scene)
72     : effectBuffer_(MAX_CHANNEL_NUM * DEFAULT_FRAME_LEN)
73 {
74     const std::unordered_map<AudioEffectMode, std::string> &audioSupportedSceneModes = GetAudioSupportedSceneModes();
75 
76     sceneType_ = scene;
77     effectMode_ = audioSupportedSceneModes.find(EFFECT_DEFAULT)->second;
78     audioBufIn_.frameLength = 0;
79     audioBufOut_.frameLength = 0;
80     ioBufferConfig_.inputCfg.samplingRate = DEFAULT_SAMPLE_RATE;
81     ioBufferConfig_.inputCfg.channels = DEFAULT_NUM_CHANNEL;
82     ioBufferConfig_.inputCfg.format = DATA_FORMAT_F32;
83     ioBufferConfig_.inputCfg.channelLayout = DEFAULT_NUM_CHANNELLAYOUT;
84     ioBufferConfig_.outputCfg.samplingRate = DEFAULT_SAMPLE_RATE;
85     ioBufferConfig_.outputCfg.channels = DEFAULT_NUM_CHANNEL;
86     ioBufferConfig_.outputCfg.format = DATA_FORMAT_F32;
87     ioBufferConfig_.outputCfg.channelLayout = DEFAULT_NUM_CHANNELLAYOUT;
88     dumpNameIn_ = "dump_effect_in_" + scene + "_"
89         + std::to_string(ioBufferConfig_.inputCfg.samplingRate) + "_"
90         + std::to_string(ioBufferConfig_.inputCfg.channels) + "_4_"
91         + GetTime() + ".pcm";
92     dumpNameOut_ = "dump_effect_out_" + scene + "_"
93         + std::to_string(ioBufferConfig_.outputCfg.samplingRate) + "_"
94         + std::to_string(ioBufferConfig_.outputCfg.channels) + "_4_"
95         + GetTime() + ".pcm";
96     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpNameIn_, &dumpFileInput_);
97     DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_SERVER_PARA, dumpNameOut_, &dumpFileOutput_);
98 }
99 #endif
100 
~AudioEffectChain()101 AudioEffectChain::~AudioEffectChain()
102 {
103     ReleaseEffectChain();
104     DumpFileUtil::CloseDumpFile(&dumpFileInput_);
105     DumpFileUtil::CloseDumpFile(&dumpFileOutput_);
106 }
107 
SetEffectMode(const std::string & mode)108 void AudioEffectChain::SetEffectMode(const std::string &mode)
109 {
110     effectMode_ = mode;
111 }
112 
SetExtraSceneType(const std::string & extraSceneType)113 void AudioEffectChain::SetExtraSceneType(const std::string &extraSceneType)
114 {
115     CHECK_AND_RETURN_LOG(StringConverter(extraSceneType, extraEffectChainType_),
116         "convert invalid extraSceneType: %{public}s", extraSceneType.c_str());
117 }
118 
SetFoldState(const std::string & foldState)119 void AudioEffectChain::SetFoldState(const std::string &foldState)
120 {
121     CHECK_AND_RETURN_LOG(StringConverter(foldState, foldState_),
122         "convert invalid foldState: %{public}s", foldState.c_str());
123 }
124 
SetLidState(const std::string & lidState)125 void AudioEffectChain::SetLidState(const std::string &lidState)
126 {
127     CHECK_AND_RETURN_LOG(StringConverter(lidState, lidState_),
128         "convert invalid lidState: %{public}s", lidState.c_str());
129 }
130 
SetEffectCurrSceneType(AudioEffectScene currSceneType)131 void AudioEffectChain::SetEffectCurrSceneType(AudioEffectScene currSceneType)
132 {
133     currSceneType_ = currSceneType;
134 }
135 
SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType)136 void AudioEffectChain::SetSpatializationSceneType(AudioSpatializationSceneType spatializationSceneType)
137 {
138     spatializationSceneType_ = spatializationSceneType;
139 }
140 
SetSpatializationEnabled(bool enabled)141 void AudioEffectChain::SetSpatializationEnabled(bool enabled)
142 {
143     spatializationEnabled_ = enabled;
144     spatializationEnabledFading_ = enabled;
145 }
146 
SetSpatializationEnabledForFading(bool enabled)147 void AudioEffectChain::SetSpatializationEnabledForFading(bool enabled)
148 {
149     std::lock_guard<std::mutex> lock(reloadMutex_);
150     CHECK_AND_RETURN_LOG(spatializationEnabledFading_ != enabled,
151         "no need to update spatialization enabled for fading: %{public}d", enabled);
152     spatializationEnabledFading_ = enabled;
153     fadingCounts_ = CROSS_FADE_FRAME_COUNT;
154 }
155 
SetStreamUsage(const int32_t streamUsage)156 void AudioEffectChain::SetStreamUsage(const int32_t streamUsage)
157 {
158     streamUsage_ = static_cast<StreamUsage>(streamUsage);
159 }
160 
ReleaseEffectChain()161 void AudioEffectChain::ReleaseEffectChain()
162 {
163     std::lock_guard<std::mutex> lock(reloadMutex_);
164     for (uint32_t i = 0; i < standByEffectHandles_.size() && i < libHandles_.size(); ++i) {
165         if (!libHandles_[i]) {
166             continue;
167         }
168         if (!standByEffectHandles_[i]) {
169             continue;
170         }
171         if (!libHandles_[i]->releaseEffect) {
172             continue;
173         }
174         libHandles_[i]->releaseEffect(standByEffectHandles_[i]);
175     }
176     standByEffectHandles_.clear();
177     libHandles_.clear();
178 }
179 
SetEffectParamToHandle(AudioEffectHandle handle,int32_t & replyData)180 int32_t AudioEffectChain::SetEffectParamToHandle(AudioEffectHandle handle, int32_t &replyData)
181 {
182     AudioEffectConfig tmpIoBufferConfig = ioBufferConfig_;
183     AudioEffectTransInfo cmdInfo = {sizeof(AudioEffectConfig), &tmpIoBufferConfig};
184     AudioEffectTransInfo replyInfo = {sizeof(int32_t), &replyData};
185     std::vector<uint8_t> paramBuffer(sizeof(AudioEffectParam) + MAX_PARAM_INDEX * sizeof(int32_t));
186     // Set param
187     AudioEffectParam *effectParam = reinterpret_cast<AudioEffectParam*>(paramBuffer.data());
188     effectParam->status = 0;
189     effectParam->paramSize = sizeof(int32_t);
190     effectParam->valueSize = 0;
191     int32_t *data = &(effectParam->data[0]);
192     data[COMMAND_CODE_INDEX] = EFFECT_SET_PARAM;
193     data[SCENE_TYPE_INDEX] = static_cast<int32_t>(currSceneType_);
194     data[EFFECT_MODE_INDEX] = GetKeyFromValue(GetAudioSupportedSceneModes(), effectMode_);
195 #ifdef WINDOW_MANAGER_ENABLE
196     std::shared_ptr<AudioEffectRotation> audioEffectRotation = AudioEffectRotation::GetInstance();
197     if (audioEffectRotation == nullptr) {
198         data[ROTATION_INDEX] = 0;
199     } else {
200         data[ROTATION_INDEX] = static_cast<int32_t>(audioEffectRotation->GetRotation());
201     }
202 #else
203     data[ROTATION_INDEX] = 0;
204 #endif
205     data[VOLUME_INDEX] = static_cast<int32_t>(finalVolume_ * MAX_UINT_VOLUME);
206     data[EXTRA_SCENE_TYPE_INDEX] = static_cast<int32_t>(extraEffectChainType_);
207     data[SPATIAL_DEVICE_TYPE_INDEX] = spatialDeviceType_;
208     data[SPATIALIZATION_SCENE_TYPE_INDEX] = spatializationSceneType_;
209     data[SPATIALIZATION_ENABLED_INDEX] = spatializationEnabled_;
210     data[STREAM_USAGE_INDEX] = streamUsage_;
211     data[FOLD_STATE_INDEX] = static_cast<int32_t>(foldState_);
212     data[LID_STATE_INDEX] = static_cast<int32_t>(lidState_);
213     data[ABS_VOLUME_STATE] = static_cast<int32_t>(absVolumeState_);
214     AUDIO_INFO_LOG("set param to handle, sceneType: %{public}d, effectMode: %{public}d, rotation: %{public}d, "
215         "volume: %{public}d, extraSceneType: %{public}d, spatialDeviceType: %{public}d, "
216         "spatializationSceneType: %{public}d, spatializationEnabled: %{public}d, streamUsage: %{public}d,"
217         "absVolumeState = %{public}d",
218         data[SCENE_TYPE_INDEX], data[EFFECT_MODE_INDEX], data[ROTATION_INDEX], data[VOLUME_INDEX],
219         data[EXTRA_SCENE_TYPE_INDEX], data[SPATIAL_DEVICE_TYPE_INDEX], data[SPATIALIZATION_SCENE_TYPE_INDEX],
220         data[SPATIALIZATION_ENABLED_INDEX], data[STREAM_USAGE_INDEX], data[ABS_VOLUME_STATE]);
221     cmdInfo = {sizeof(AudioEffectParam) + sizeof(int32_t) * MAX_PARAM_INDEX, effectParam};
222     int32_t ret = (*handle)->command(handle, EFFECT_CMD_SET_PARAM, &cmdInfo, &replyInfo);
223     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "[%{public}s] with mode [%{public}s], NUM_SET_EFFECT_PARAM fail",
224         sceneType_.c_str(), effectMode_.c_str());
225 
226     cmdInfo = {sizeof(AudioEffectConfig), &tmpIoBufferConfig};
227     ret = (*handle)->command(handle, EFFECT_CMD_GET_CONFIG, &cmdInfo, &cmdInfo);
228     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "EFFECT_CMD_GET_CONFIG fail, ret is %{public}d", ret);
229 
230     ioBufferConfig_.outputCfg.channels = tmpIoBufferConfig.outputCfg.channels;
231     ioBufferConfig_.outputCfg.channelLayout = tmpIoBufferConfig.outputCfg.channelLayout;
232     return SUCCESS;
233 }
234 
SetEffectProperty(const std::string & effect,const std::string & property)235 int32_t AudioEffectChain::SetEffectProperty(const std::string &effect, const std::string &property)
236 {
237     std::lock_guard<std::mutex> lock(reloadMutex_);
238     int32_t ret = 0;
239     int32_t size = standByEffectHandles_.size();
240     for (int32_t index = 0; index < size; index++) {
241         auto &handle = standByEffectHandles_[index];
242         auto const &effectName = effectNames_[index];
243         if (effect == effectName) {
244             int32_t replyData = 0;
245             const char *propCstr = property.c_str();
246             AudioEffectTransInfo cmdInfo = {sizeof(const char *), reinterpret_cast<void*>(&propCstr)};
247             AudioEffectTransInfo replyInfo = {sizeof(int32_t), &replyData};
248             ret = (*handle)->command(handle, EFFECT_CMD_SET_PROPERTY, &cmdInfo, &replyInfo);
249             CHECK_AND_RETURN_RET_LOG(ret == 0, ret,
250                 "[%{public}s] with mode [%{public}s], %{public}s effect EFFECT_CMD_SET_PROPERTY fail",
251                 sceneType_.c_str(), effectMode_.c_str(), effectName.c_str());
252         }
253     }
254     UpdateMultichannelIoBufferConfigInner();
255     return ret;
256 }
257 
CheckHandleAndRelease(AudioEffectHandle handle,AudioEffectLibrary * libHandle,int32_t ret)258 static int32_t CheckHandleAndRelease(AudioEffectHandle handle, AudioEffectLibrary *libHandle, int32_t ret)
259 {
260     if (ret != SUCCESS) {
261         libHandle->releaseEffect(handle);
262     }
263     return ret;
264 }
265 
AddEffectHandle(AudioEffectHandle handle,AudioEffectLibrary * libHandle,AudioEffectScene currSceneType,const std::string & effectName,const std::string & effectProperty)266 void AudioEffectChain::AddEffectHandle(AudioEffectHandle handle, AudioEffectLibrary *libHandle,
267     AudioEffectScene currSceneType, const std::string &effectName, const std::string &effectProperty)
268 {
269     int32_t ret;
270     int32_t replyData = 0;
271     int32_t latencyData = 0;
272     currSceneType_ = currSceneType;
273     AudioEffectTransInfo cmdInfo = {sizeof(AudioEffectConfig), &ioBufferConfig_};
274     AudioEffectTransInfo replyInfo = {sizeof(int32_t), &replyData};
275 
276     ret = (*handle)->command(handle, EFFECT_CMD_INIT, &cmdInfo, &replyInfo);
277     CHECK_AND_RETURN_LOG(CheckHandleAndRelease(handle, libHandle, ret) == SUCCESS,
278         "[%{public}s] with mode [%{public}s], %{public}s effect EFFECT_CMD_INIT fail",
279         sceneType_.c_str(), effectMode_.c_str(), effectName.c_str());
280     ret = (*handle)->command(handle, EFFECT_CMD_ENABLE, &cmdInfo, &replyInfo);
281     CHECK_AND_RETURN_LOG(CheckHandleAndRelease(handle, libHandle, ret) == SUCCESS,
282         "[%{public}s] with mode [%{public}s], %{public}s effect EFFECT_CMD_ENABLE fail",
283         sceneType_.c_str(), effectMode_.c_str(), effectName.c_str());
284     ret = SetEffectParamToHandle(handle, latencyData);
285     CHECK_AND_RETURN_LOG(CheckHandleAndRelease(handle, libHandle, ret) == SUCCESS,
286         "[%{public}s] with mode [%{public}s], %{public}s effect EFFECT_CMD_SET_PARAM fail",
287         sceneType_.c_str(), effectMode_.c_str(), effectName.c_str());
288 
289     if (!effectProperty.empty()) {
290         const char *propCstr = effectProperty.c_str();
291         cmdInfo = {sizeof(const char *), &propCstr};
292         ret = (*handle)->command(handle, EFFECT_CMD_SET_PROPERTY, &cmdInfo, &replyInfo);
293         CHECK_AND_RETURN_LOG(CheckHandleAndRelease(handle, libHandle, ret) == SUCCESS,
294             "[%{public}s] with mode [%{public}s], %{public}s effect EFFECT_CMD_SET_PROPERTY fail",
295             sceneType_.c_str(), effectMode_.c_str(), effectName.c_str());
296     }
297     if (preIoBufferConfig_.inputCfg.channels == 0 && preIoBufferConfig_.inputCfg.channelLayout == 0) {
298         preIoBufferConfig_ = ioBufferConfig_;
299     }
300     cmdInfo = {sizeof(AudioEffectConfig), &preIoBufferConfig_};
301     ret = (*handle)->command(handle, EFFECT_CMD_SET_CONFIG, &cmdInfo, &replyInfo);
302     CHECK_AND_RETURN_LOG(CheckHandleAndRelease(handle, libHandle, ret) == SUCCESS,
303         "[%{public}s] with mode [%{public}s], %{public}s effect EFFECT_CMD_SET_CONFIG fail",
304         sceneType_.c_str(), effectMode_.c_str(), effectName.c_str());
305 
306     ret = (*handle)->command(handle, EFFECT_CMD_GET_CONFIG, &cmdInfo, &cmdInfo);
307     CHECK_AND_RETURN_LOG(CheckHandleAndRelease(handle, libHandle, ret) == SUCCESS,
308         "[%{public}s] with mode [%{public}s], %{public}s effect EFFECT_CMD_GET_CONFIG fail",
309         sceneType_.c_str(), effectMode_.c_str(), effectName.c_str());
310     preIoBufferConfig_.inputCfg = preIoBufferConfig_.outputCfg;
311     ioBufferConfig_.outputCfg.channels = preIoBufferConfig_.outputCfg.channels;
312     ioBufferConfig_.outputCfg.channelLayout = preIoBufferConfig_.outputCfg.channelLayout;
313 
314     standByEffectHandles_.emplace_back(handle);
315     effectNames_.emplace_back(effectName);
316     libHandles_.emplace_back(libHandle);
317     latency_ += static_cast<uint32_t>(latencyData);
318 }
319 
UpdateEffectParam()320 int32_t AudioEffectChain::UpdateEffectParam()
321 {
322     std::lock_guard<std::mutex> lock(reloadMutex_);
323     return UpdateEffectParamInner();
324 }
325 
ApplyEffectChain(float * bufIn,float * bufOut,uint32_t frameLen,AudioEffectProcInfo procInfo)326 void AudioEffectChain::ApplyEffectChain(float *bufIn, float *bufOut, uint32_t frameLen, AudioEffectProcInfo procInfo)
327 {
328     size_t inTotlen = frameLen * ioBufferConfig_.inputCfg.channels * sizeof(float);
329     size_t outTotlen = frameLen * ioBufferConfig_.outputCfg.channels * sizeof(float);
330     DumpFileUtil::WriteDumpFile(dumpFileInput_, static_cast<void *>(bufIn), inTotlen);
331     DumpEffectProcessData(dumpNameIn_, static_cast<void *>(bufIn), inTotlen);
332 
333     if (IsEmptyEffectHandles()) {
334         CHECK_AND_RETURN_LOG(memcpy_s(bufOut, outTotlen, bufIn, outTotlen) == 0, "memcpy error in apply effect");
335         DumpFileUtil::WriteDumpFile(dumpFileOutput_, static_cast<void *>(bufOut), outTotlen);
336         return;
337     }
338 
339 #ifdef SENSOR_ENABLE
340     int32_t replyData = 0;
341     auto imuData = headTracker_->GetHeadPostureData();
342     AudioEffectTransInfo cmdInfo = {sizeof(HeadPostureData), &imuData};
343     AudioEffectTransInfo replyInfo = {sizeof(int32_t), &replyData};
344 #endif
345 
346     audioBufIn_.frameLength = frameLen;
347     audioBufOut_.frameLength = frameLen;
348     std::lock_guard<std::mutex> lock(reloadMutex_);
349 
350     for (size_t i = 0; i < standByEffectHandles_.size(); ++i) {
351 #ifdef SENSOR_ENABLE
352         if ((!procInfo.btOffloadEnabled) && procInfo.headTrackingEnabled) {
353             (*standByEffectHandles_[i])->command(standByEffectHandles_[i], EFFECT_CMD_SET_IMU, &cmdInfo, &replyInfo);
354         }
355 #endif
356         audioBufIn_.raw = i == 0 ? bufIn : effectBuffer_.data();
357         audioBufOut_.raw = i == (standByEffectHandles_.size() - 1) ? bufOut : effectBuffer_.data();
358 
359         int32_t ret = (*standByEffectHandles_[i])->process(standByEffectHandles_[i], &audioBufIn_, &audioBufOut_);
360         CHECK_AND_CONTINUE_LOG(ret == 0, "[%{public}s] with mode [%{public}s], either one of libs process fail",
361             sceneType_.c_str(), effectMode_.c_str());
362     }
363 
364     CrossFadeProcess(bufOut, frameLen);
365 
366     DumpFileUtil::WriteDumpFile(dumpFileOutput_, static_cast<void *>(bufOut), outTotlen);
367 }
368 
UpdateBufferConfig(uint32_t & channels,uint64_t & channelLayout)369 void AudioEffectChain::UpdateBufferConfig(uint32_t &channels, uint64_t &channelLayout)
370 {
371     channels = ioBufferConfig_.outputCfg.channels;
372     channelLayout = ioBufferConfig_.outputCfg.channelLayout;
373 }
374 
IsEmptyEffectHandles()375 bool AudioEffectChain::IsEmptyEffectHandles()
376 {
377     std::lock_guard<std::mutex> lock(reloadMutex_);
378     return standByEffectHandles_.size() == 0;
379 }
380 
UpdateMultichannelIoBufferConfig(const uint32_t & channels,const uint64_t & channelLayout)381 int32_t AudioEffectChain::UpdateMultichannelIoBufferConfig(const uint32_t &channels, const uint64_t &channelLayout)
382 {
383     if (ioBufferConfig_.inputCfg.channels == channels && ioBufferConfig_.inputCfg.channelLayout == channelLayout) {
384         return SUCCESS;
385     }
386     ioBufferConfig_.inputCfg.channels = channels;
387     ioBufferConfig_.inputCfg.channelLayout = channelLayout;
388     if (IsEmptyEffectHandles()) {
389         return SUCCESS;
390     }
391     std::lock_guard<std::mutex> lock(reloadMutex_);
392     UpdateMultichannelIoBufferConfigInner();
393     return SUCCESS;
394 }
395 
ResetIoBufferConfig()396 void AudioEffectChain::ResetIoBufferConfig()
397 {
398     ioBufferConfig_.inputCfg.channels = DEFAULT_NUM_CHANNEL;
399     ioBufferConfig_.inputCfg.channelLayout = DEFAULT_NUM_CHANNELLAYOUT;
400     ioBufferConfig_.outputCfg.channels = DEFAULT_NUM_CHANNEL;
401     ioBufferConfig_.outputCfg.channelLayout = DEFAULT_NUM_CHANNELLAYOUT;
402     dumpNameIn_ = "dump_effect_in_" + sceneType_ + "_"
403         + std::to_string(ioBufferConfig_.inputCfg.samplingRate) + "_"
404         + std::to_string(ioBufferConfig_.inputCfg.channels) + "_4.pcm";
405     dumpNameOut_ = "dump_effect_out_" + sceneType_ + "_"
406         + std::to_string(ioBufferConfig_.outputCfg.samplingRate) + "_"
407         + std::to_string(ioBufferConfig_.outputCfg.channels) + "_4.pcm";
408 }
409 
GetIoBufferConfig()410 AudioEffectConfig AudioEffectChain::GetIoBufferConfig()
411 {
412     return ioBufferConfig_;
413 }
414 
StoreOldEffectChainInfo(std::string & sceneMode,AudioEffectConfig & ioBufferConfig)415 void AudioEffectChain::StoreOldEffectChainInfo(std::string &sceneMode, AudioEffectConfig &ioBufferConfig)
416 {
417     sceneMode = effectMode_;
418     ioBufferConfig = GetIoBufferConfig();
419     return;
420 }
421 
GetLatency()422 uint32_t AudioEffectChain::GetLatency()
423 {
424     return latency_;
425 }
426 
DumpEffectProcessData(std::string fileName,void * buffer,size_t len)427 void AudioEffectChain::DumpEffectProcessData(std::string fileName, void *buffer, size_t len)
428 {
429     if (AudioDump::GetInstance().GetVersionType() == DumpFileUtil::BETA_VERSION) {
430         AudioCacheMgr::GetInstance().CacheData(fileName, buffer, len);
431     }
432 }
433 
434 #ifdef SENSOR_ENABLE
SetHeadTrackingDisabled()435 void AudioEffectChain::SetHeadTrackingDisabled()
436 {
437     if (IsEmptyEffectHandles()) {
438         return;
439     }
440 
441     std::lock_guard<std::mutex> lock(reloadMutex_);
442     for (AudioEffectHandle handle : standByEffectHandles_) {
443         int32_t replyData = 0;
444         HeadPostureData imuDataDisabled = {1, 1.0, 0.0, 0.0, 0.0};
445         AudioEffectTransInfo cmdInfo = {sizeof(HeadPostureData), &imuDataDisabled};
446         AudioEffectTransInfo replyInfo = {sizeof(int32_t), &replyData};
447         int32_t ret = (*handle)->command(handle, EFFECT_CMD_SET_IMU, &cmdInfo, &replyInfo);
448         if (ret != SUCCESS) {
449             AUDIO_WARNING_LOG("SetHeadTrackingDisabled failed");
450         }
451     }
452 }
453 #endif
454 
InitEffectChain()455 void AudioEffectChain::InitEffectChain()
456 {
457     if (IsEmptyEffectHandles()) {
458         return;
459     }
460     std::lock_guard<std::mutex> lock(reloadMutex_);
461     for (AudioEffectHandle handle : standByEffectHandles_) {
462         int32_t replyData = 0;
463         AudioEffectTransInfo cmdInfo = {sizeof(int32_t), &replyData};
464         AudioEffectTransInfo replyInfo = {sizeof(int32_t), &replyData};
465         int32_t ret = (*handle)->command(handle, EFFECT_CMD_ENABLE, &cmdInfo, &replyInfo);
466         CHECK_AND_RETURN_LOG(ret == 0, "[%{public}s] with mode [%{public}s], either one of libs EFFECT_CMD_ENABLE fail",
467             sceneType_.c_str(), effectMode_.c_str());
468     }
469 }
470 
SetFinalVolume(const float volume)471 void AudioEffectChain::SetFinalVolume(const float volume)
472 {
473     finalVolume_ = volume;
474 }
475 
GetFinalVolume()476 float AudioEffectChain::GetFinalVolume()
477 {
478     return finalVolume_;
479 }
480 
SetCurrVolume(const float volume)481 void AudioEffectChain::SetCurrVolume(const float volume)
482 {
483     currVolume_ = volume;
484 }
485 
GetCurrVolume()486 float AudioEffectChain::GetCurrVolume()
487 {
488     return currVolume_;
489 }
490 
SetFinalVolumeState(const bool state)491 void AudioEffectChain::SetFinalVolumeState(const bool state)
492 {
493     sendFinalVolumeState_ = state;
494 }
495 
GetFinalVolumeState()496 bool AudioEffectChain::GetFinalVolumeState()
497 {
498     return sendFinalVolumeState_;
499 }
500 
SetSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType)501 void AudioEffectChain::SetSpatialDeviceType(AudioSpatialDeviceType spatialDeviceType)
502 {
503     spatialDeviceType_ = spatialDeviceType;
504 
505     return;
506 }
SetCurrChannelNoCheck(const uint32_t channel)507 void AudioEffectChain::SetCurrChannelNoCheck(const uint32_t channel)
508 {
509     currChannelNoCheck_ = channel;
510 }
511 
SetCurrChannelLayoutNoCheck(const uint64_t channelLayout)512 void AudioEffectChain::SetCurrChannelLayoutNoCheck(const uint64_t channelLayout)
513 {
514     currchannelLayoutNoCheck_ = channelLayout;
515 }
516 
GetInputChannelInfo(uint32_t & channels,uint64_t & channelLayout)517 void AudioEffectChain::GetInputChannelInfo(uint32_t &channels, uint64_t &channelLayout)
518 {
519     channels = ioBufferConfig_.inputCfg.channels;
520     channelLayout = ioBufferConfig_.inputCfg.channelLayout;
521 }
522 
CheckChannelLayoutByReplyInfo(AudioEffectTransInfo info)523 bool AudioEffectChain::CheckChannelLayoutByReplyInfo(AudioEffectTransInfo info)
524 {
525     if (info.data == nullptr) {
526         return false;
527     }
528     int32_t *channelLayoutSupportedFlage = static_cast<int32_t *>(info.data);
529     if (*channelLayoutSupportedFlage != SUCCESS) {
530         return false;
531     }
532     return true;
533 }
534 
updatePrimaryChannel()535 int32_t AudioEffectChain::updatePrimaryChannel()
536 {
537     ioBufferConfig_.inputCfg.channels = currChannelNoCheck_;
538     ioBufferConfig_.inputCfg.channelLayout = currchannelLayoutNoCheck_;
539     int32_t replyData = -1;
540     AudioEffectConfig tmpIoBufferConfig = ioBufferConfig_;
541     AudioEffectTransInfo cmdInfo = {sizeof(AudioEffectConfig), &tmpIoBufferConfig};
542     AudioEffectTransInfo replyInfo = {sizeof(int32_t), &replyData};
543     AudioEffectHandle preHandle = nullptr;
544     tmpIoBufferConfig.outputCfg.channels = 0;
545     tmpIoBufferConfig.outputCfg.channelLayout = 0;
546     bool isSupportedChannelLayoutFlage = true;
547     for (AudioEffectHandle handle : standByEffectHandles_) {
548         if (preHandle != nullptr) {
549             int32_t ret = (*preHandle)->command(preHandle, EFFECT_CMD_SET_CONFIG, &cmdInfo, &replyInfo);
550             CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "Multichannel effect chain update EFFECT_CMD_SET_CONFIG fail");
551             isSupportedChannelLayoutFlage = CheckChannelLayoutByReplyInfo(replyInfo);
552             if (isSupportedChannelLayoutFlage == false) {
553                 ioBufferConfig_.inputCfg.channels = DEFAULT_NUM_CHANNEL;
554                 ioBufferConfig_.inputCfg.channelLayout = DEFAULT_NUM_CHANNELLAYOUT;
555                 AUDIO_INFO_LOG("currChannelLayout is not supported, change to default channelLayout");
556                 return ERROR;
557             }
558 
559             ret = (*preHandle)->command(preHandle, EFFECT_CMD_GET_CONFIG, &cmdInfo, &cmdInfo);
560             CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "Multichannel effect chain update EFFECT_CMD_GET_CONFIG fail");
561             tmpIoBufferConfig.inputCfg = tmpIoBufferConfig.outputCfg;
562         }
563         preHandle = handle;
564     }
565     tmpIoBufferConfig.outputCfg.channels = DEFAULT_NUM_CHANNEL;
566     tmpIoBufferConfig.outputCfg.channelLayout = DEFAULT_NUM_CHANNELLAYOUT;
567     if (preHandle == nullptr) {
568         return ERROR;
569     }
570     int32_t ret = (*preHandle)->command(preHandle, EFFECT_CMD_SET_CONFIG, &cmdInfo, &replyInfo);
571     CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "last effect update EFFECT_CMD_SET_CONFIG fail");
572     isSupportedChannelLayoutFlage = CheckChannelLayoutByReplyInfo(replyInfo);
573     if (isSupportedChannelLayoutFlage == false) {
574         ioBufferConfig_.inputCfg.channels = DEFAULT_NUM_CHANNEL;
575         ioBufferConfig_.inputCfg.channelLayout = DEFAULT_NUM_CHANNELLAYOUT;
576         AUDIO_INFO_LOG("currChannelLayout is not supported, change to default channelLayout");
577         return ERROR;
578     }
579 
580     ret = (*preHandle)->command(preHandle, EFFECT_CMD_GET_CONFIG, &cmdInfo, &cmdInfo);
581     CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "last effect update EFFECT_CMD_GET_CONFIG fail");
582 
583     ioBufferConfig_.outputCfg.channels = tmpIoBufferConfig.outputCfg.channels;
584     ioBufferConfig_.outputCfg.channelLayout = tmpIoBufferConfig.outputCfg.channelLayout;
585     updateDumpName(); // update dumpFile name(effect_in and effect_out)
586     return SUCCESS;
587 }
588 
updateDumpName()589 void AudioEffectChain::updateDumpName()
590 {
591     dumpNameIn_ = "dump_effect_in_" + sceneType_ + "_"
592         + std::to_string(ioBufferConfig_.inputCfg.samplingRate) + "_"
593         + std::to_string(ioBufferConfig_.inputCfg.channels) + "_4.pcm";
594     dumpNameOut_ = "dump_effect_out_" + sceneType_ + "_"
595         + std::to_string(ioBufferConfig_.outputCfg.samplingRate) + "_"
596         + std::to_string(ioBufferConfig_.outputCfg.channels) + "_4.pcm";
597 }
598 
UpdateMultichannelIoBufferConfigInner()599 int32_t AudioEffectChain::UpdateMultichannelIoBufferConfigInner()
600 {
601     if (updatePrimaryChannel() == SUCCESS) {
602         return SUCCESS;
603     }
604     int32_t replyData = 0;
605     AudioEffectConfig tmpIoBufferConfig = ioBufferConfig_;
606     AudioEffectTransInfo cmdInfo = {sizeof(AudioEffectConfig), &tmpIoBufferConfig};
607     AudioEffectTransInfo replyInfo = {sizeof(int32_t), &replyData};
608     AudioEffectHandle preHandle = nullptr;
609     tmpIoBufferConfig.outputCfg.channels = 0;
610     tmpIoBufferConfig.outputCfg.channelLayout = 0;
611     for (AudioEffectHandle handle : standByEffectHandles_) {
612         if (preHandle != nullptr) {
613             int32_t ret = (*preHandle)->command(preHandle, EFFECT_CMD_SET_CONFIG, &cmdInfo, &replyInfo);
614             CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "Multichannel effect chain update EFFECT_CMD_SET_CONFIG fail");
615 
616             ret = (*preHandle)->command(preHandle, EFFECT_CMD_GET_CONFIG, &cmdInfo, &cmdInfo);
617             CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "Multichannel effect chain update EFFECT_CMD_GET_CONFIG fail");
618             tmpIoBufferConfig.inputCfg = tmpIoBufferConfig.outputCfg;
619         }
620         preHandle = handle;
621     }
622     tmpIoBufferConfig.outputCfg.channels = DEFAULT_NUM_CHANNEL;
623     tmpIoBufferConfig.outputCfg.channelLayout = DEFAULT_NUM_CHANNELLAYOUT;
624     if (preHandle == nullptr) {
625         return ERROR;
626     }
627     int32_t ret = (*preHandle)->command(preHandle, EFFECT_CMD_SET_CONFIG, &cmdInfo, &replyInfo);
628     CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "last effect update EFFECT_CMD_SET_CONFIG fail");
629 
630     ret = (*preHandle)->command(preHandle, EFFECT_CMD_GET_CONFIG, &cmdInfo, &cmdInfo);
631     CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "last effect update EFFECT_CMD_GET_CONFIG fail");
632 
633     ioBufferConfig_.outputCfg.channels = tmpIoBufferConfig.outputCfg.channels;
634     ioBufferConfig_.outputCfg.channelLayout = tmpIoBufferConfig.outputCfg.channelLayout;
635     updateDumpName(); // update dumpFile name(effect_in and effect_out)
636     return SUCCESS;
637 }
638 
UpdateEffectParamInner()639 int32_t AudioEffectChain::UpdateEffectParamInner()
640 {
641     latency_ = 0;
642     for (AudioEffectHandle handle : standByEffectHandles_) {
643         int32_t replyData;
644         int32_t ret = SetEffectParamToHandle(handle, replyData);
645         CHECK_AND_RETURN_RET_LOG(ret == 0, ret, "set EFFECT_CMD_SET_PARAM fail");
646         AUDIO_DEBUG_LOG("Set Effect Param Scene Type: %{public}d Success", currSceneType_);
647         latency_ += static_cast<uint32_t>(replyData);
648     }
649     UpdateMultichannelIoBufferConfigInner();
650     return SUCCESS;
651 }
652 
CrossFadeProcess(float * bufOut,uint32_t frameLen)653 void AudioEffectChain::CrossFadeProcess(float *bufOut, uint32_t frameLen)
654 {
655     if (fadingCounts_ == 0) {
656         return;
657     }
658 
659     int32_t channelNum = static_cast<int32_t>(ioBufferConfig_.outputCfg.channels);
660     int32_t frameLength = static_cast<int32_t>(frameLen);
661 
662     // fading out to zero
663     if (fadingCounts_ > 0) {
664         for (int32_t i = 0; i < frameLength; ++i) {
665             for (int32_t j = 0; j < channelNum; ++j) {
666                 bufOut[i * channelNum + j] *=
667                     (fadingCounts_ * frameLength - i) / static_cast<float>(frameLength * CROSS_FADE_FRAME_COUNT);
668             }
669         }
670         fadingCounts_--;
671         // fading out finish, update spatialization enabled and start fading in
672         if (fadingCounts_ == 0) {
673             fadingCounts_ = -CROSS_FADE_FRAME_COUNT;
674             spatializationEnabled_ = spatializationEnabledFading_;
675             UpdateEffectParamInner();
676             AUDIO_INFO_LOG("fading out finish, switch to %{public}d and start fading in", spatializationEnabled_);
677         }
678         return;
679     }
680 
681     // fading in to one
682     if (fadingCounts_ < 0) {
683         for (int32_t i = 0; i < frameLength; ++i) {
684             for (int32_t j = 0; j < channelNum; ++j) {
685                 bufOut[i * channelNum + j] *=
686                     (1 + (fadingCounts_ * frameLength + i) / static_cast<float>(frameLength * CROSS_FADE_FRAME_COUNT));
687             }
688         }
689         fadingCounts_++;
690         // fading in finish, start normally processing
691         if (fadingCounts_ == 0) {
692             AUDIO_INFO_LOG("fading in finish, start normally processing for %{public}d", spatializationEnabled_);
693         }
694         return;
695     }
696 }
697 
SetAbsVolumeStateToEffectChain(const bool absVolumeState)698 void AudioEffectChain::SetAbsVolumeStateToEffectChain(const bool absVolumeState)
699 {
700     absVolumeState_ = absVolumeState;
701 }
702 } // namespace AudioStandard
703 } // namespace OHOS
704