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