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