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