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