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