xref: /aosp_15_r20/frameworks/av/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <cstddef>
18 #include <cstdio>
19 
20 #define LOG_TAG "BundleContext"
21 #include <android-base/logging.h>
22 #include <audio_utils/power.h>
23 #include <media/AidlConversionCppNdk.h>
24 #include <Utils.h>
25 
26 #include "BundleContext.h"
27 #include "BundleTypes.h"
28 #include "math.h"
29 
30 namespace aidl::android::hardware::audio::effect {
31 
32 using ::aidl::android::media::audio::common::AudioChannelLayout;
33 using ::aidl::android::media::audio::common::AudioDeviceDescription;
34 using ::aidl::android::media::audio::common::AudioDeviceType;
35 
BundleContext(int statusDepth,const Parameter::Common & common,const lvm::BundleEffectType & type)36 BundleContext::BundleContext(int statusDepth, const Parameter::Common& common,
37               const lvm::BundleEffectType& type)
38         : EffectContext(statusDepth, common), mType(type) {
39     int inputChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
40             common.input.base.channelMask);
41     mSamplesPerSecond = common.input.base.sampleRate * inputChannelCount;
42 }
43 
~BundleContext()44 BundleContext::~BundleContext() {
45     deInit();
46 }
47 
init()48 RetCode BundleContext::init() {
49     // init with pre-defined preset NORMAL
50     for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
51         mBandGainmB[i] = lvm::kSoftPresets[0 /* normal */][i] * 100;
52     }
53 
54     // Initialise control params
55     LVM_ControlParams_t controlParams;
56     RetCode retStatus = initControlParameter(controlParams);
57     RETURN_VALUE_IF(retStatus != RetCode::SUCCESS, RetCode::ERROR_ILLEGAL_PARAMETER,
58                     " UnsupportedParams");
59 
60     // allocate lvm instance
61     LVM_ReturnStatus_en status;
62     LVM_InstParams_t params = {.BufferMode = LVM_UNMANAGED_BUFFERS,
63                                .MaxBlockSize = lvm::MAX_CALL_SIZE,
64                                .EQNB_NumBands = lvm::MAX_NUM_BANDS,
65                                .PSA_Included = LVM_PSA_ON};
66     status = LVM_GetInstanceHandle(&mInstance, &params);
67     GOTO_IF_LVM_ERROR(status, deinit, "LVM_GetInstanceHandleFailed");
68 
69     // set control
70     status = LVM_SetControlParameters(mInstance, &controlParams);
71     GOTO_IF_LVM_ERROR(status, deinit, "LVM_SetControlParametersFailed");
72 
73     /* Set the headroom parameters */
74     LVM_HeadroomParams_t headroomParams;
75     initHeadroomParameter(headroomParams);
76     status = LVM_SetHeadroomParams(mInstance, &headroomParams);
77     GOTO_IF_LVM_ERROR(status, deinit, "LVM_SetHeadroomParamsFailed");
78 
79     return RetCode::SUCCESS;
80 
81 deinit:
82     deInit();
83     return RetCode::ERROR_EFFECT_LIB_ERROR;
84 }
85 
deInit()86 void BundleContext::deInit() {
87     if (mInstance) {
88         LVM_DelInstanceHandle(&mInstance);
89         mInstance = nullptr;
90     }
91 }
92 
setCommon(const Parameter::Common & common)93 RetCode BundleContext::setCommon(const Parameter::Common& common) {
94     RetCode ret = EffectContext::setCommon(common);
95     RETURN_VALUE_IF(ret != RetCode::SUCCESS, ret, " setCommonFailed");
96     if (mInstance) {
97         LVM_ControlParams_t params;
98         RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, &params),
99                         RetCode::ERROR_EFFECT_LIB_ERROR, "failGetControlParams");
100         RETURN_VALUE_IF(RetCode::SUCCESS != applyCommonParameter(params),
101                         RetCode::ERROR_EFFECT_LIB_ERROR, " applyCommonParameterFailed");
102         RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, &params),
103                         RetCode::ERROR_EFFECT_LIB_ERROR, "failSetControlParams");
104     } else {
105         RETURN_VALUE_IF(RetCode::SUCCESS != init(), RetCode::ERROR_EFFECT_LIB_ERROR, " initFailed");
106     }
107     return RetCode::SUCCESS;
108 }
109 
enable()110 RetCode BundleContext::enable() {
111     if (mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
112     // Bass boost or Virtualizer can be temporarily disabled if playing over device speaker due to
113     // their nature.
114     bool tempDisabled = false;
115     switch (mType) {
116         case lvm::BundleEffectType::EQUALIZER:
117             if (mSamplesToExitCountEq <= 0) mNumberEffectsEnabled++;
118             mSamplesToExitCountEq = (mSamplesPerSecond * 0.1);
119             mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::EQUALIZER));
120             break;
121         case lvm::BundleEffectType::BASS_BOOST:
122             if (mSamplesToExitCountBb <= 0) mNumberEffectsEnabled++;
123             mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::BASS_BOOST));
124             mSamplesToExitCountBb = (mSamplesPerSecond * 0.1);
125             tempDisabled = mBassTempDisabled;
126             break;
127         case lvm::BundleEffectType::VIRTUALIZER:
128             if (mSamplesToExitCountVirt <= 0) mNumberEffectsEnabled++;
129             mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VIRTUALIZER));
130             mSamplesToExitCountVirt = (mSamplesPerSecond * 0.1);
131             tempDisabled = mVirtualizerTempDisabled;
132             break;
133         case lvm::BundleEffectType::VOLUME:
134             if ((mEffectInDrain & (1 << int(lvm::BundleEffectType::VOLUME))) == 0)
135                 mNumberEffectsEnabled++;
136             mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VOLUME));
137             break;
138     }
139     mEnabled = true;
140     return (tempDisabled ? RetCode::SUCCESS : enableOperatingMode());
141 }
142 
enableOperatingMode()143 RetCode BundleContext::enableOperatingMode() {
144     LVM_ControlParams_t params;
145     RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, &params),
146                     RetCode::ERROR_EFFECT_LIB_ERROR, "failGetControlParams");
147     switch (mType) {
148         case lvm::BundleEffectType::EQUALIZER:
149             params.EQNB_OperatingMode = LVM_EQNB_ON;
150             break;
151         case lvm::BundleEffectType::BASS_BOOST:
152             params.BE_OperatingMode = LVM_BE_ON;
153             break;
154         case lvm::BundleEffectType::VIRTUALIZER:
155             params.VirtualizerOperatingMode = LVM_MODE_ON;
156             break;
157         case lvm::BundleEffectType::VOLUME:
158             break;
159     }
160     RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, &params),
161                     RetCode::ERROR_EFFECT_LIB_ERROR, "failSetControlParams");
162 
163     return limitLevel();
164 }
165 
disable()166 RetCode BundleContext::disable() {
167     if (!mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
168     switch (mType) {
169         case lvm::BundleEffectType::EQUALIZER:
170             mEffectInDrain |= 1 << int(lvm::BundleEffectType::EQUALIZER);
171             break;
172         case lvm::BundleEffectType::BASS_BOOST:
173             mEffectInDrain |= 1 << int(lvm::BundleEffectType::BASS_BOOST);
174             break;
175         case lvm::BundleEffectType::VIRTUALIZER:
176             mEffectInDrain |= 1 << int(lvm::BundleEffectType::VIRTUALIZER);
177             break;
178         case lvm::BundleEffectType::VOLUME:
179             mEffectInDrain |= 1 << int(lvm::BundleEffectType::VOLUME);
180             break;
181     }
182     mEnabled = false;
183     return disableOperatingMode();
184 }
185 
disableOperatingMode()186 RetCode BundleContext::disableOperatingMode() {
187     LVM_ControlParams_t params;
188     RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, &params),
189                     RetCode::ERROR_EFFECT_LIB_ERROR, "failGetControlParams");
190     switch (mType) {
191         case lvm::BundleEffectType::EQUALIZER:
192             params.EQNB_OperatingMode = LVM_EQNB_OFF;
193             break;
194         case lvm::BundleEffectType::BASS_BOOST:
195             params.BE_OperatingMode = LVM_BE_OFF;
196             break;
197         case lvm::BundleEffectType::VIRTUALIZER:
198             params.VirtualizerOperatingMode = LVM_MODE_OFF;
199             break;
200         case lvm::BundleEffectType::VOLUME:
201             break;
202     }
203     RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, &params),
204                     RetCode::ERROR_EFFECT_LIB_ERROR, "failSetControlParams");
205     return limitLevel();
206 }
207 
limitLevel()208 RetCode BundleContext::limitLevel() {
209     int gainCorrection = 0;
210     // Count the energy contribution per band for EQ and BassBoost only if they are active.
211     float energyContribution = 0;
212     float energyCross = 0;
213     float energyBassBoost = 0;
214     float crossCorrection = 0;
215     LVM_ControlParams_t params;
216     RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, &params),
217                     RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
218 
219     bool eqEnabled = params.EQNB_OperatingMode == LVM_EQNB_ON;
220     bool bbEnabled = params.BE_OperatingMode == LVM_BE_ON;
221     bool viEnabled = params.VirtualizerOperatingMode == LVM_MODE_ON;
222 
223     if (eqEnabled) {
224         for (unsigned int i = 0; i < lvm::MAX_NUM_BANDS; i++) {
225             float bandFactor = mBandGainmB[i] / 1500.0;
226             float bandCoefficient = lvm::kBandEnergyCoefficient[i];
227             float bandEnergy = bandFactor * bandCoefficient * bandCoefficient;
228             if (bandEnergy > 0) energyContribution += bandEnergy;
229         }
230 
231         // cross EQ coefficients
232         float bandFactorSum = 0;
233         for (unsigned int i = 0; i < lvm::MAX_NUM_BANDS - 1; i++) {
234             float bandFactor1 = mBandGainmB[i] / 1500.0;
235             float bandFactor2 = mBandGainmB[i + 1] / 1500.0;
236 
237             if (bandFactor1 > 0 && bandFactor2 > 0) {
238                 float crossEnergy =
239                         bandFactor1 * bandFactor2 * lvm::kBandEnergyCrossCoefficient[i];
240                 bandFactorSum += bandFactor1 * bandFactor2;
241 
242                 if (crossEnergy > 0) energyCross += crossEnergy;
243             }
244         }
245         bandFactorSum -= 1.0;
246         if (bandFactorSum > 0) crossCorrection = bandFactorSum * 0.7;
247     }
248     // BassBoost contribution
249     if (bbEnabled) {
250         float boostFactor = mBassStrengthSaved / 1000.0;
251         float boostCoefficient = lvm::kBassBoostEnergyCoefficient;
252 
253         energyContribution += boostFactor * boostCoefficient * boostCoefficient;
254 
255         if (eqEnabled) {
256             for (unsigned int i = 0; i < lvm::MAX_NUM_BANDS; i++) {
257                 float bandFactor = mBandGainmB[i] / 1500.0;
258                 float bandCrossCoefficient = lvm::kBassBoostEnergyCrossCoefficient[i];
259                 float bandEnergy = boostFactor * bandFactor * bandCrossCoefficient;
260                 if (bandEnergy > 0) energyBassBoost += bandEnergy;
261             }
262         }
263     }
264     // Virtualizer contribution
265     if (viEnabled) {
266         energyContribution += lvm::kVirtualizerContribution * lvm::kVirtualizerContribution;
267     }
268 
269     double totalEnergyEstimation =
270             sqrt(energyContribution + energyCross + energyBassBoost) - crossCorrection;
271 
272     // roundoff
273     int maxLevelRound = (int)(totalEnergyEstimation + 0.99);
274     if (maxLevelRound + mVolumedB > 0) {
275         gainCorrection = maxLevelRound + mVolumedB;
276     }
277 
278     params.VC_EffectLevel = mVolumedB - gainCorrection;
279     if (params.VC_EffectLevel < -96) {
280         params.VC_EffectLevel = -96;
281     }
282     /* Activate the initial settings */
283     RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, &params),
284                     RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
285 
286     if (mFirstVolume) {
287         RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetVolumeNoSmoothing(mInstance, &params),
288                         RetCode::ERROR_EFFECT_LIB_ERROR, " setVolumeNoSmoothingFailed");
289         mFirstVolume = false;
290     }
291 
292     return RetCode::SUCCESS;
293 }
294 
isDeviceSupportedBassBoost(const std::vector<aidl::android::media::audio::common::AudioDeviceDescription> & devices)295 bool BundleContext::isDeviceSupportedBassBoost(
296         const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
297     for (const auto& device : devices) {
298         if (device != AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER, ""} &&
299             device != AudioDeviceDescription{AudioDeviceType::OUT_CARKIT,
300                                              AudioDeviceDescription::CONNECTION_BT_SCO} &&
301             device != AudioDeviceDescription{AudioDeviceType::OUT_SPEAKER,
302                                              AudioDeviceDescription::CONNECTION_BT_A2DP} &&
303             device != AudioDeviceDescription{AudioDeviceType::OUT_SUBMIX,
304                                              AudioDeviceDescription::CONNECTION_VIRTUAL}) {
305             return false;
306         }
307     }
308     return true;
309 }
310 
isDeviceSupportedVirtualizer(const std::vector<aidl::android::media::audio::common::AudioDeviceDescription> & devices)311 bool BundleContext::isDeviceSupportedVirtualizer(
312         const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
313     for (const auto& device : devices) {
314         if (device != AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
315                                              AudioDeviceDescription::CONNECTION_ANALOG} &&
316             device != AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
317                                              AudioDeviceDescription::CONNECTION_ANALOG} &&
318             device != AudioDeviceDescription{AudioDeviceType::OUT_HEADPHONE,
319                                              AudioDeviceDescription::CONNECTION_BT_A2DP} &&
320             device != AudioDeviceDescription{AudioDeviceType::OUT_HEADSET,
321                                              AudioDeviceDescription::CONNECTION_USB} &&
322             device != AudioDeviceDescription{AudioDeviceType::OUT_SUBMIX,
323                                              AudioDeviceDescription::CONNECTION_VIRTUAL}) {
324             return false;
325         }
326     }
327     return true;
328 }
329 
isConfigSupportedVirtualizer(size_t channelCount,const AudioDeviceDescription & device)330 bool BundleContext::isConfigSupportedVirtualizer(size_t channelCount,
331                                                  const AudioDeviceDescription& device) {
332     return (channelCount >= 1 && channelCount <= FCC_2) && isDeviceSupportedVirtualizer({device});
333 }
334 
setOutputDevice(const std::vector<aidl::android::media::audio::common::AudioDeviceDescription> & devices)335 RetCode BundleContext::setOutputDevice(
336         const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& devices) {
337     mOutputDevice = devices;
338     switch (mType) {
339         case lvm::BundleEffectType::BASS_BOOST:
340             if (!isDeviceSupportedBassBoost(devices)) {
341                 // If a device doesn't support bass boost, the effect must be temporarily disabled.
342                 // The effect must still report its original state as this can only be changed by
343                 // the start/stop commands.
344                 if (mEnabled) {
345                     disableOperatingMode();
346                 }
347                 mBassTempDisabled = true;
348             } else {
349                 // If a device supports bass boost and the effect has been temporarily disabled
350                 // previously then re-enable it
351                 if (!mEnabled) {
352                     enableOperatingMode();
353                 }
354                 mBassTempDisabled = false;
355             }
356             break;
357         case lvm::BundleEffectType::VIRTUALIZER:
358             if (!isDeviceSupportedVirtualizer(devices)) {
359                 if (mEnabled) {
360                     disableOperatingMode();
361                 }
362                 mVirtualizerTempDisabled = true;
363             } else {
364                 if (!mEnabled) {
365                     enableOperatingMode();
366                 }
367                 mVirtualizerTempDisabled = false;
368             }
369             break;
370         default:
371             break;
372     }
373     return RetCode::SUCCESS;
374 }
375 
LVC_ToDB_s32Tos16(LVM_INT32 Lin_fix) const376 LVM_INT16 BundleContext::LVC_ToDB_s32Tos16(LVM_INT32 Lin_fix) const {
377     LVM_INT16 db_fix;
378     LVM_INT16 Shift;
379     LVM_INT16 SmallRemainder;
380     LVM_UINT32 Remainder = (LVM_UINT32)Lin_fix;
381 
382     /* Count leading bits, 1 cycle in assembly*/
383     for (Shift = 0; Shift < 32; Shift++) {
384         if ((Remainder & 0x80000000U) != 0) {
385             break;
386         }
387         Remainder = Remainder << 1;
388     }
389 
390     /*
391      * Based on the approximation equation (for Q11.4 format):
392      *
393      * dB = -96 * Shift + 16 * (8 * Remainder - 2 * Remainder^2)
394      */
395     db_fix = (LVM_INT16)(-96 * Shift); /* Six dB steps in Q11.4 format*/
396     SmallRemainder = (LVM_INT16)((Remainder & 0x7fffffff) >> 24);
397     db_fix = (LVM_INT16)(db_fix + SmallRemainder);
398     SmallRemainder = (LVM_INT16)(SmallRemainder * SmallRemainder);
399     db_fix = (LVM_INT16)(db_fix - (LVM_INT16)((LVM_UINT16)SmallRemainder >> 9));
400 
401     /* Correct for small offset */
402     db_fix = (LVM_INT16)(db_fix - 5);
403 
404     return db_fix;
405 }
406 
407 /* static */
VolToDb(float vol)408 float BundleContext::VolToDb(float vol) {
409     float dB = audio_utils_power_from_amplitude(vol);
410     return std::max(dB, -96.f);
411 }
412 
setVolumeStereo(const Parameter::VolumeStereo & volume)413 RetCode BundleContext::setVolumeStereo(const Parameter::VolumeStereo& volume) {
414     LVM_ControlParams_t params;
415 
416     // Convert volume to dB
417     float leftdB = VolToDb(volume.left);
418     float rightdB = VolToDb(volume.right);
419 
420     float maxdB = std::max(leftdB, rightdB);
421     float pandB = rightdB - leftdB;
422     setVolumeLevel(maxdB);
423 
424     RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, &params),
425                     RetCode::ERROR_EFFECT_LIB_ERROR, "");
426     params.VC_Balance = pandB;
427 
428     RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, &params),
429                     RetCode::ERROR_EFFECT_LIB_ERROR, "");
430     mVolumeStereo = volume;
431     return RetCode::SUCCESS;
432 }
433 
setEqualizerPreset(const std::size_t presetIdx)434 RetCode BundleContext::setEqualizerPreset(const std::size_t presetIdx) {
435     if (presetIdx < 0 || presetIdx >= lvm::MAX_NUM_PRESETS) {
436         return RetCode::ERROR_ILLEGAL_PARAMETER;
437     }
438 
439     std::vector<Equalizer::BandLevel> bandLevels;
440     bandLevels.reserve(lvm::MAX_NUM_BANDS);
441     for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
442         bandLevels.emplace_back(Equalizer::BandLevel{static_cast<int32_t>(i),
443                                                      lvm::kSoftPresets[presetIdx][i] * 100});
444     }
445 
446     RetCode ret = updateControlParameter(bandLevels);
447     if (RetCode::SUCCESS == ret) {
448         mCurPresetIdx = presetIdx;
449     } else {
450         LOG(ERROR) << __func__ << " failed to setPreset " << presetIdx;
451     }
452     return ret;
453 }
454 
setEqualizerBandLevels(const std::vector<Equalizer::BandLevel> & bandLevels)455 RetCode BundleContext::setEqualizerBandLevels(const std::vector<Equalizer::BandLevel>& bandLevels) {
456     RETURN_VALUE_IF(bandLevels.size() > lvm::MAX_NUM_BANDS || bandLevels.empty(),
457                     RetCode::ERROR_ILLEGAL_PARAMETER, "sizeExceedMax");
458 
459     RetCode ret = updateControlParameter(bandLevels);
460     if (RetCode::SUCCESS == ret) {
461         mCurPresetIdx = lvm::PRESET_CUSTOM;
462     } else {
463         LOG(ERROR) << __func__ << " failed with " << ::android::internal::ToString(bandLevels);
464     }
465     return ret;
466 }
467 
getEqualizerBandLevels() const468 std::vector<Equalizer::BandLevel> BundleContext::getEqualizerBandLevels() const {
469     std::vector<Equalizer::BandLevel> bandLevels;
470     bandLevels.reserve(lvm::MAX_NUM_BANDS);
471     for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
472         bandLevels.emplace_back(Equalizer::BandLevel{static_cast<int32_t>(i), mBandGainmB[i]});
473     }
474     return bandLevels;
475 }
476 
getEqualizerCenterFreqs()477 std::vector<int32_t> BundleContext::getEqualizerCenterFreqs() {
478     std::vector<int32_t> freqs;
479     LVM_ControlParams_t params;
480     /* Get the current settings */
481     RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, &params), freqs,
482                     " getControlParamFailed");
483     for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
484         freqs.push_back((int32_t)params.pEQNB_BandDefinition[i].Frequency * 1000);
485     }
486 
487     return freqs;
488 }
489 
isBandLevelIndexInRange(const std::vector<Equalizer::BandLevel> & bandLevels) const490 bool BundleContext::isBandLevelIndexInRange(
491         const std::vector<Equalizer::BandLevel>& bandLevels) const {
492     const auto [min, max] =
493             std::minmax_element(bandLevels.begin(), bandLevels.end(),
494                                 [](const auto& a, const auto& b) { return a.index < b.index; });
495     return min->index >= 0 && static_cast<size_t>(max->index) < lvm::MAX_NUM_BANDS;
496 }
497 
updateControlParameter(const std::vector<Equalizer::BandLevel> & bandLevels)498 RetCode BundleContext::updateControlParameter(const std::vector<Equalizer::BandLevel>& bandLevels) {
499     RETURN_VALUE_IF(!isBandLevelIndexInRange(bandLevels), RetCode::ERROR_ILLEGAL_PARAMETER,
500                     "indexOutOfRange");
501 
502     std::array<int, lvm::MAX_NUM_BANDS> tempLevel(mBandGainmB);
503     for (const auto& it : bandLevels) {
504         tempLevel[it.index] = it.levelMb;
505     }
506 
507     LVM_ControlParams_t params;
508     RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, &params),
509                     RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
510 
511     for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
512         params.pEQNB_BandDefinition[i].Frequency = lvm::kPresetsFrequencies[i];
513         params.pEQNB_BandDefinition[i].QFactor = lvm::kPresetsQFactors[i];
514         params.pEQNB_BandDefinition[i].Gain =
515                 tempLevel[i] > 0 ? (tempLevel[i] + 50) / 100 : (tempLevel[i] - 50) / 100;
516     }
517 
518     RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, &params),
519                     RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
520 
521     mBandGainmB = tempLevel;
522     return RetCode::SUCCESS;
523 }
524 
setBassBoostStrength(int strength)525 RetCode BundleContext::setBassBoostStrength(int strength) {
526     // Update Control Parameter
527     LVM_ControlParams_t params;
528     RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, &params),
529                     RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
530 
531     params.BE_EffectLevel = (LVM_INT16)((15 * strength) / 1000);
532     params.BE_CentreFreq = LVM_BE_CENTRE_90Hz;
533 
534     RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, &params),
535                     RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
536 
537     mBassStrengthSaved = strength;
538     return limitLevel();
539 }
540 
setVolumeLevel(float level)541 RetCode BundleContext::setVolumeLevel(float level) {
542     if (mMuteEnabled) {
543         mLevelSaveddB = level;
544     } else {
545         mVolumedB = level;
546     }
547     return limitLevel();
548 }
549 
getVolumeLevel() const550 float BundleContext::getVolumeLevel() const {
551     return (mMuteEnabled ? mLevelSaveddB : mVolumedB);
552 }
553 
setVolumeMute(bool mute)554 RetCode BundleContext::setVolumeMute(bool mute) {
555     mMuteEnabled = mute;
556     if (mMuteEnabled) {
557         mLevelSaveddB = mVolumedB;
558         mVolumedB = -96;
559     } else {
560         mVolumedB = mLevelSaveddB;
561     }
562     return limitLevel();
563 }
564 
setVirtualizerStrength(int strength)565 RetCode BundleContext::setVirtualizerStrength(int strength) {
566     // Update Control Parameter
567     LVM_ControlParams_t params;
568     RETURN_VALUE_IF(LVM_SUCCESS != LVM_GetControlParameters(mInstance, &params),
569                     RetCode::ERROR_EFFECT_LIB_ERROR, " getControlParamFailed");
570 
571     params.CS_EffectLevel = ((strength * 32767) / 1000);
572 
573     RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, &params),
574                     RetCode::ERROR_EFFECT_LIB_ERROR, " setControlParamFailed");
575 
576     mVirtStrengthSaved = strength;
577     return limitLevel();
578 }
579 
580 
setForcedDevice(const::aidl::android::media::audio::common::AudioDeviceDescription & device)581 RetCode BundleContext::setForcedDevice(
582         const ::aidl::android::media::audio::common::AudioDeviceDescription& device) {
583     RetCode ret = RetCode::SUCCESS;
584     bool enableVirtualizer = mType == lvm::BundleEffectType::VIRTUALIZER && mEnabled;
585 
586     if (isDeviceSupportedVirtualizer({device})) {
587         mVirtualizerForcedDevice = device;
588     } else {
589         // disabling forced virtualization mode
590         AudioDeviceDescription noneDevice;
591         if (device != noneDevice) {
592             // device is not supported, make it behave as a reset of forced mode but return an error
593             ret = RetCode::ERROR_ILLEGAL_PARAMETER;
594         }
595         // verify whether the virtualization should be enabled or disabled
596         if (!isDeviceSupportedVirtualizer(mOutputDevice)) {
597             enableVirtualizer = false;
598         }
599         mVirtualizerForcedDevice = noneDevice;
600     }
601 
602     if (enableVirtualizer) {
603         if (mVirtualizerTempDisabled) {
604             LOG(VERBOSE) << __func__ << " re-enable virtualizer";
605             enableOperatingMode();
606             mVirtualizerTempDisabled = false;
607         }
608     } else {
609         if (!mVirtualizerTempDisabled) {
610             LOG(VERBOSE) << __func__ << " disable virtualizer";
611             disableOperatingMode();
612             mVirtualizerTempDisabled = true;
613         }
614     }
615 
616     return ret;
617 }
618 
applyCommonParameter(LVM_ControlParams_t & params) const619 RetCode BundleContext::applyCommonParameter(LVM_ControlParams_t& params) const {
620     int outputChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
621             mCommon.output.base.channelMask);
622     auto outputChannelMaskConv = aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
623             mCommon.output.base.channelMask, /*isInput*/ false);
624     RETURN_VALUE_IF(!outputChannelMaskConv.ok(), RetCode::ERROR_ILLEGAL_PARAMETER,
625                     " outputChannelMaskNotValid");
626 
627     params.NrChannels = outputChannelCount;
628     params.ChMask = outputChannelMaskConv.value();
629     params.SampleRate = lvmFsForSampleRate(mCommon.input.base.sampleRate);
630 
631     int inputChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
632             mCommon.input.base.channelMask);
633     if (inputChannelCount == 1) {
634         params.SourceFormat = LVM_MONO;
635     } else if (inputChannelCount == 2) {
636         params.SourceFormat = LVM_STEREO;
637     } else if (inputChannelCount > 2 && inputChannelCount <= LVM_MAX_CHANNELS) {
638         params.SourceFormat = LVM_MULTICHANNEL;
639     }
640 
641     return RetCode::SUCCESS;
642 }
643 
initControlParameter(LVM_ControlParams_t & params) const644 RetCode BundleContext::initControlParameter(LVM_ControlParams_t& params) const {
645     RETURN_VALUE_IF(RetCode::SUCCESS != applyCommonParameter(params),
646                     RetCode::ERROR_EFFECT_LIB_ERROR, " applyCommonParameterFailed");
647 
648     /* General parameters */
649     params.OperatingMode = LVM_MODE_ON;
650     params.SpeakerType = LVM_HEADPHONES;
651 
652     /* Concert Sound parameters */
653     params.VirtualizerOperatingMode = LVM_MODE_OFF;
654     params.VirtualizerType = LVM_CONCERTSOUND;
655     params.VirtualizerReverbLevel = 100;
656     params.CS_EffectLevel = LVM_CS_EFFECT_NONE;
657 
658     params.EQNB_OperatingMode = LVM_EQNB_OFF;
659     params.EQNB_NBands = lvm::MAX_NUM_BANDS;
660     params.pEQNB_BandDefinition = getDefaultEqualizerBandDefs();
661 
662     /* Volume Control parameters */
663     params.VC_EffectLevel = 0;
664     params.VC_Balance = 0;
665 
666     /* Treble Enhancement parameters */
667     params.TE_OperatingMode = LVM_TE_OFF;
668     params.TE_EffectLevel = 0;
669 
670     /* PSA Control parameters */
671     params.PSA_Enable = LVM_PSA_OFF;
672     params.PSA_PeakDecayRate = (LVM_PSA_DecaySpeed_en)0;
673 
674     /* Bass Enhancement parameters */
675     params.BE_OperatingMode = LVM_BE_OFF;
676     params.BE_EffectLevel = 0;
677     params.BE_CentreFreq = LVM_BE_CENTRE_90Hz;
678     params.BE_HPF = LVM_BE_HPF_ON;
679 
680     /* PSA Control parameters */
681     params.PSA_Enable = LVM_PSA_OFF;
682     params.PSA_PeakDecayRate = LVM_PSA_SPEED_MEDIUM;
683 
684     return RetCode::SUCCESS;
685 }
686 
initHeadroomParameter(LVM_HeadroomParams_t & params) const687 void BundleContext::initHeadroomParameter(LVM_HeadroomParams_t& params) const {
688     params.pHeadroomDefinition = getDefaultEqualizerHeadroomBanDefs();
689     params.NHeadroomBands = 2;
690     params.Headroom_OperatingMode = LVM_HEADROOM_OFF;
691 }
692 
getDefaultEqualizerBandDefs()693 LVM_EQNB_BandDef_t *BundleContext::getDefaultEqualizerBandDefs() {
694     static LVM_EQNB_BandDef_t* BandDefs = []() {
695         static LVM_EQNB_BandDef_t tempDefs[lvm::MAX_NUM_BANDS];
696         /* N-Band Equaliser parameters */
697         for (std::size_t i = 0; i < lvm::MAX_NUM_BANDS; i++) {
698             tempDefs[i].Frequency = lvm::kPresetsFrequencies[i];
699             tempDefs[i].QFactor = lvm::kPresetsQFactors[i];
700             tempDefs[i].Gain = lvm::kSoftPresets[0/* normal */][i];
701         }
702         return tempDefs;
703     }();
704 
705     return BandDefs;
706 }
707 
getDefaultEqualizerHeadroomBanDefs()708 LVM_HeadroomBandDef_t *BundleContext::getDefaultEqualizerHeadroomBanDefs() {
709     static LVM_HeadroomBandDef_t HeadroomBandDef[LVM_HEADROOM_MAX_NBANDS] = {
710             {
711                     .Limit_Low = 20,
712                     .Limit_High = 4999,
713                     .Headroom_Offset = 0,
714             },
715             {
716                     .Limit_Low = 5000,
717                     .Limit_High = 24000,
718                     .Headroom_Offset = 0,
719             },
720     };
721     return HeadroomBandDef;
722 }
723 
getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload)724 std::vector<Virtualizer::ChannelAngle> BundleContext::getSpeakerAngles(
725         const Virtualizer::SpeakerAnglesPayload payload) {
726     std::vector<Virtualizer::ChannelAngle> angles;
727     auto chCount = ::aidl::android::hardware::audio::common::getChannelCount(payload.layout);
728     RETURN_VALUE_IF(!isConfigSupportedVirtualizer(chCount, payload.device), angles,
729                     "payloadNotSupported");
730 
731     if (chCount == 1) {
732         angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
733                    .azimuthDegree = 0,
734                    .elevationDegree = 0}};
735     } else {
736         angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
737                    .azimuthDegree = -90,
738                    .elevationDegree = 0},
739                   {.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_RIGHT,
740                    .azimuthDegree = 90,
741                    .elevationDegree = 0}};
742     }
743     return angles;
744 }
745 
process(float * in,float * out,int samples)746 IEffect::Status BundleContext::process(float* in, float* out, int samples) {
747     IEffect::Status status = {EX_NULL_POINTER, 0, 0};
748     RETURN_VALUE_IF(!in, status, "nullInput");
749     RETURN_VALUE_IF(!out, status, "nullOutput");
750     status = {EX_ILLEGAL_STATE, 0, 0};
751     int64_t inputFrameCount = getCommon().input.frameCount;
752     int64_t outputFrameCount = getCommon().output.frameCount;
753     RETURN_VALUE_IF(inputFrameCount != outputFrameCount, status, "FrameCountMismatch");
754     int isDataAvailable = true;
755 
756     auto frameSize = getInputFrameSize();
757     RETURN_VALUE_IF(0 == frameSize, status, "zeroFrameSize");
758 
759     if ((mEffectProcessCalled & 1 << int(mType)) != 0) {
760         const int undrainedEffects = mEffectInDrain & ~mEffectProcessCalled;
761         if ((undrainedEffects & 1 << int(lvm::BundleEffectType::EQUALIZER)) != 0) {
762             mSamplesToExitCountEq = 0;
763             --mNumberEffectsEnabled;
764             mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::EQUALIZER));
765         }
766         if ((undrainedEffects & 1 << int(lvm::BundleEffectType::BASS_BOOST)) != 0) {
767             mSamplesToExitCountBb = 0;
768             --mNumberEffectsEnabled;
769             mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::BASS_BOOST));
770         }
771         if ((undrainedEffects & 1 << int(lvm::BundleEffectType::VIRTUALIZER)) != 0) {
772             mSamplesToExitCountVirt = 0;
773             --mNumberEffectsEnabled;
774             mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VIRTUALIZER));
775         }
776         if ((undrainedEffects & 1 << int(lvm::BundleEffectType::VOLUME)) != 0) {
777             --mNumberEffectsEnabled;
778             mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VOLUME));
779         }
780     }
781     mEffectProcessCalled |= 1 << int(mType);
782     if (!mEnabled) {
783         switch (mType) {
784             case lvm::BundleEffectType::EQUALIZER:
785                 if (mSamplesToExitCountEq > 0) {
786                     mSamplesToExitCountEq -= samples;
787                 }
788                 if (mSamplesToExitCountEq <= 0) {
789                     isDataAvailable = false;
790                     if ((mEffectInDrain & 1 << int(lvm::BundleEffectType::EQUALIZER)) != 0) {
791                         mNumberEffectsEnabled--;
792                         mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::EQUALIZER));
793                     }
794                 }
795                 break;
796             case lvm::BundleEffectType::BASS_BOOST:
797                 if (mSamplesToExitCountBb > 0) {
798                     mSamplesToExitCountBb -= samples;
799                 }
800                 if (mSamplesToExitCountBb <= 0) {
801                     isDataAvailable = false;
802                     if ((mEffectInDrain & 1 << int(lvm::BundleEffectType::BASS_BOOST)) != 0) {
803                         mNumberEffectsEnabled--;
804                         mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::BASS_BOOST));
805                     }
806                 }
807                 break;
808             case lvm::BundleEffectType::VIRTUALIZER:
809                 if (mSamplesToExitCountVirt > 0) {
810                     mSamplesToExitCountVirt -= samples;
811                 }
812                 if (mSamplesToExitCountVirt <= 0) {
813                     isDataAvailable = false;
814                     if ((mEffectInDrain & 1 << int(lvm::BundleEffectType::VIRTUALIZER)) != 0) {
815                         mNumberEffectsEnabled--;
816                         mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VIRTUALIZER));
817                     }
818                 }
819                 break;
820             case lvm::BundleEffectType::VOLUME:
821                 isDataAvailable = false;
822                 if ((mEffectInDrain & 1 << int(lvm::BundleEffectType::VOLUME)) != 0) {
823                     mNumberEffectsEnabled--;
824                     mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VOLUME));
825                 }
826                 break;
827         }
828     }
829     if (isDataAvailable) {
830         mNumberEffectsCalled++;
831     }
832 
833     if (mNumberEffectsCalled >= mNumberEffectsEnabled) {
834         // We expect the # effects called to be equal to # effects enabled in sequence (including
835         // draining effects).  Warn if this is not the case due to inconsistent calls.
836         ALOGW_IF(mNumberEffectsCalled > mNumberEffectsEnabled,
837                  "%s Number of effects called %d is greater than number of effects enabled %d",
838                  __func__, mNumberEffectsCalled, mNumberEffectsEnabled);
839         mEffectProcessCalled = 0;  // reset our consistency check.
840         mNumberEffectsCalled = 0;
841         int frames = samples * sizeof(float) / frameSize;
842         int bufferIndex = 0;
843         // LVM library supports max of int16_t frames at a time and should be multiple of
844         // kBlockSizeMultiple.
845         constexpr int kBlockSizeMultiple = 4;
846         constexpr int kMaxBlockFrames =
847                 (std::numeric_limits<int16_t>::max() / kBlockSizeMultiple) * kBlockSizeMultiple;
848         while (frames > 0) {
849             /* Process the samples */
850             LVM_ReturnStatus_en lvmStatus;
851             int processFrames = std::min(frames, kMaxBlockFrames);
852             lvmStatus = LVM_Process(mInstance, in + bufferIndex, out + bufferIndex,
853                                     processFrames, 0);
854             if (lvmStatus != LVM_SUCCESS) {
855                 LOG(ERROR) << "LVM_Process failed with error: " << lvmStatus;
856                 return {EX_UNSUPPORTED_OPERATION, 0, 0};
857             }
858             frames -= processFrames;
859             int processedSize = processFrames * frameSize / sizeof(float);
860             bufferIndex += processedSize;
861         }
862     } else {
863         for (int i = 0; i < samples; i++) {
864             out[i] = in[i];
865         }
866     }
867     return {STATUS_OK, samples, samples};
868 }
869 
870 }  // namespace aidl::android::hardware::audio::effect
871