Merge "Volume : Add libeffect bundle implementation" am: f460b58fb9 am: 5047bd3075

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/2366808

Change-Id: I5e62042e1152cfae726e2f35a91d1e803af23a07
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
index 1bcde74..9c7c312 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
@@ -96,8 +96,11 @@
             mSamplesToExitCountVirt = (mSamplesPerSecond * 0.1);
             tempDisabled = mVirtualizerTempDisabled;
             break;
-        default:
-            // Add handling for other effects
+        case lvm::BundleEffectType::VOLUME:
+            LOG(DEBUG) << __func__ << " enable bundle VOL";
+            if ((mEffectInDrain & (1 << int(lvm::BundleEffectType::VOLUME))) == 0)
+                mNumberEffectsEnabled++;
+            mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VOLUME));
             break;
     }
     mEnabled = true;
@@ -123,8 +126,8 @@
                 LOG(DEBUG) << __func__ << " enable bundle VR";
                 params.VirtualizerOperatingMode = LVM_MODE_ON;
                 break;
-            default:
-                // Add handling for other effects
+            case lvm::BundleEffectType::VOLUME:
+                LOG(DEBUG) << __func__ << " enable bundle VOL";
                 break;
         }
         RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, &params),
@@ -148,8 +151,9 @@
             LOG(DEBUG) << __func__ << " disable bundle VR";
             mEffectInDrain |= 1 << int(lvm::BundleEffectType::VIRTUALIZER);
             break;
-        default:
-            // Add handling for other effects
+        case lvm::BundleEffectType::VOLUME:
+            LOG(DEBUG) << __func__ << " disable bundle VOL";
+            mEffectInDrain |= 1 << int(lvm::BundleEffectType::VOLUME);
             break;
     }
     mEnabled = false;
@@ -175,8 +179,8 @@
                 LOG(DEBUG) << __func__ << " disable bundle VR";
                 params.VirtualizerOperatingMode = LVM_MODE_OFF;
                 break;
-            default:
-                // Add handling for other effects
+            case lvm::BundleEffectType::VOLUME:
+                LOG(DEBUG) << __func__ << " disable bundle VOL";
                 break;
         }
         RETURN_VALUE_IF(LVM_SUCCESS != LVM_SetControlParameters(mInstance, &params),
@@ -255,15 +259,15 @@
 
         // roundoff
         int maxLevelRound = (int)(totalEnergyEstimation + 0.99);
-        if (maxLevelRound + mLevelSaved > 0) {
-            gainCorrection = maxLevelRound + mLevelSaved;
+        if (maxLevelRound + mVolume > 0) {
+            gainCorrection = maxLevelRound + mVolume;
         }
 
-        params.VC_EffectLevel = mLevelSaved - gainCorrection;
+        params.VC_EffectLevel = mVolume - gainCorrection;
         if (params.VC_EffectLevel < -96) {
             params.VC_EffectLevel = -96;
         }
-        LOG(INFO) << "\tVol: " << mLevelSaved << ", GainCorrection: " << gainCorrection
+        LOG(INFO) << "\tVol: " << mVolume << ", GainCorrection: " << gainCorrection
                   << ", Actual vol: " << params.VC_EffectLevel;
 
         /* Activate the initial settings */
@@ -395,8 +399,7 @@
     int rightdB = VolToDb(volume.right);
     int maxdB = std::max(leftdB, rightdB);
     int pandB = rightdB - leftdB;
-    // TODO: add volume effect implementation here:
-    // android::VolumeSetVolumeLevel(pContext, (int16_t)(maxdB * 100));
+    setVolumeLevel(maxdB * 100);
     LOG(DEBUG) << __func__ << " pandB: " << pandB << " maxdB " << maxdB;
 
     {
@@ -519,6 +522,35 @@
     return limitLevel();
 }
 
+RetCode BundleContext::setVolumeLevel(int level) {
+    if (level < Volume::MIN_LEVEL_DB || level > lvm::kVolumeCap.maxLevel) {
+        return RetCode::ERROR_ILLEGAL_PARAMETER;
+    }
+
+    if (mMuteEnabled) {
+        mLevelSaved = level / 100;
+    } else {
+        mVolume = level / 100;
+    }
+    LOG(INFO) << __func__ << " success with level " << level;
+    return limitLevel();
+}
+
+int BundleContext::getVolumeLevel() const {
+    return (mMuteEnabled ? mLevelSaved * 100 : mVolume * 100);
+}
+
+RetCode BundleContext::setVolumeMute(bool mute) {
+    mMuteEnabled = mute;
+    if (mMuteEnabled) {
+        mLevelSaved = mVolume;
+        mVolume = -96;
+    } else {
+        mVolume = mLevelSaved;
+    }
+    return limitLevel();
+}
+
 RetCode BundleContext::setVirtualizerStrength(int strength) {
     if (strength < Virtualizer::MIN_PER_MILLE_STRENGTH ||
         strength > Virtualizer::MAX_PER_MILLE_STRENGTH) {
@@ -662,6 +694,11 @@
             --mNumberEffectsEnabled;
             mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VIRTUALIZER));
         }
+        if ((undrainedEffects & 1 << int(lvm::BundleEffectType::VOLUME)) != 0) {
+            LOG(DEBUG) << "Draining VOLUME";
+            --mNumberEffectsEnabled;
+            mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VOLUME));
+        }
     }
     mEffectProcessCalled |= 1 << int(mType);
     if (!mEnabled) {
@@ -705,8 +742,13 @@
                     LOG(DEBUG) << "Effect_process() this is the last frame for VIRTUALIZER";
                 }
                 break;
-            default:
-                // Add handling for other effects
+            case lvm::BundleEffectType::VOLUME:
+                isDataAvailable = false;
+                if ((mEffectInDrain & 1 << int(lvm::BundleEffectType::VOLUME)) != 0) {
+                    mNumberEffectsEnabled--;
+                    mEffectInDrain &= ~(1 << int(lvm::BundleEffectType::VOLUME));
+                }
+                LOG(DEBUG) << "Effect_process() LVM_VOLUME Effect is not enabled";
                 break;
         }
     }
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
index 116ae6f..be723f7 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
@@ -71,6 +71,12 @@
     RetCode setBassBoostStrength(int strength);
     int getBassBoostStrength() const { return mBassStrengthSaved; }
 
+    RetCode setVolumeLevel(int level);
+    int getVolumeLevel() const;
+
+    RetCode setVolumeMute(bool mute);
+    int getVolumeMute() const { return mMuteEnabled; }
+
     RetCode setVirtualizerStrength(int strength);
     int getVirtualizerStrength() const { return mVirtStrengthSaved; }
 
@@ -106,7 +112,7 @@
     int mEffectProcessCalled = 0;
     int mNumberEffectsEnabled = 0;
     int mNumberEffectsCalled = 0;
-    bool mFirstVolume = false;
+    bool mFirstVolume = true;
     // Bass
     bool mBassTempDisabled = false;
     int mBassStrengthSaved = 0;
@@ -118,6 +124,7 @@
     bool mVirtualizerTempDisabled = false;
     // Volume
     int mLevelSaved = 0; /* for when mute is set, level must be saved */
+    int mVolume = 0;
     bool mMuteEnabled = false; /* Must store as mute = -96dB level */
 
     void initControlParameter(LVM_ControlParams_t& params) const;
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
index 95a0dab..16917f0 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
@@ -121,8 +121,22 @@
                    .implementor = "NXP Software Ltd."},
         .capability = Capability::make<Capability::virtualizer>(kVirtualizerCap)};
 
-// TODO: add descriptors for other bundle effect types here.
-static const Descriptor kVolumeDesc;
+static const Volume::Capability kVolumeCap = {.maxLevel = Volume::MAX_LEVEL_DB};
+
+static const std::string kVolumeEffectName = "Volume";
+
+static const Descriptor kVolumeDesc = {
+        .common = {.id = {.type = kVolumeTypeUUID,
+                          .uuid = kVolumeBundleImplUUID,
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::LAST,
+                             .volume = Flags::Volume::CTRL},
+                   .cpuLoad = VOLUME_CUP_LOAD_ARM9E,
+                   .memoryUsage = BUNDLE_MEM_USAGE,
+                   .name = kVolumeEffectName,
+                   .implementor = "NXP Software Ltd."},
+        .capability = Capability::make<Capability::volume>(kVolumeCap)};
 
 /* The following tables have been computed using the actual levels measured by the output of
  * white noise or pink noise (IEC268-1) for the EQ and BassBoost Effects. These are estimates of
diff --git a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
index b435ab4..81b8aca 100644
--- a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.cpp
@@ -35,12 +35,13 @@
 using aidl::android::hardware::audio::effect::kBassBoostBundleImplUUID;
 using aidl::android::hardware::audio::effect::kEqualizerBundleImplUUID;
 using aidl::android::hardware::audio::effect::kVirtualizerBundleImplUUID;
+using aidl::android::hardware::audio::effect::kVolumeBundleImplUUID;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioUuid;
 
 bool isUuidSupported(const AudioUuid* uuid) {
     return (*uuid == kEqualizerBundleImplUUID || *uuid == kBassBoostBundleImplUUID ||
-            *uuid == kVirtualizerBundleImplUUID);
+            *uuid == kVirtualizerBundleImplUUID || *uuid == kVolumeBundleImplUUID);
 }
 
 extern "C" binder_exception_t createEffect(const AudioUuid* uuid,
@@ -70,6 +71,8 @@
         *_aidl_return = aidl::android::hardware::audio::effect::lvm:: kBassBoostDesc;
     } else if (*in_impl_uuid == kVirtualizerBundleImplUUID) {
         *_aidl_return = aidl::android::hardware::audio::effect::lvm::kVirtualizerDesc;
+    } else if (*in_impl_uuid == kVolumeBundleImplUUID) {
+        *_aidl_return = aidl::android::hardware::audio::effect::lvm::kVolumeDesc;
     }
     return EX_NONE;
 }
@@ -90,9 +93,12 @@
         mType = lvm::BundleEffectType::VIRTUALIZER;
         mDescriptor = &lvm::kVirtualizerDesc;
         mEffectName = &lvm::kVirtualizerEffectName;
+    } else if (uuid == kVolumeBundleImplUUID) {
+        mType = lvm::BundleEffectType::VOLUME;
+        mDescriptor = &lvm::kVolumeDesc;
+        mEffectName = &lvm::kVolumeEffectName;
     } else {
-        // TODO: add other bundle effect types here.
-        LOG(ERROR) << __func__ << uuid.toString() << " not supported yet!";
+        LOG(ERROR) << __func__ << uuid.toString() << " not supported!";
     }
 }
 
@@ -156,6 +162,8 @@
             return setParameterBassBoost(specific);
         case Parameter::Specific::virtualizer:
             return setParameterVirtualizer(specific);
+        case Parameter::Specific::volume:
+            return setParameterVolume(specific);
         default:
             LOG(ERROR) << __func__ << " unsupported tag " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
@@ -217,6 +225,26 @@
     }
 }
 
+ndk::ScopedAStatus EffectBundleAidl::setParameterVolume(const Parameter::Specific& specific) {
+    auto& vol = specific.get<Parameter::Specific::volume>();
+    auto volTag = vol.getTag();
+    switch (volTag) {
+        case Volume::levelDb: {
+            RETURN_IF(mContext->setVolumeLevel(vol.get<Volume::levelDb>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case Volume::mute:
+            RETURN_IF(mContext->setVolumeMute(vol.get<Volume::mute>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setMuteFailed");
+            return ndk::ScopedAStatus::ok();
+        default:
+            LOG(ERROR) << __func__ << " unsupported parameter " << specific.toString();
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "volTagNotSupported");
+    }
+}
+
 ndk::ScopedAStatus EffectBundleAidl::getParameterSpecific(const Parameter::Id& id,
                                                           Parameter::Specific* specific) {
     RETURN_IF(!specific, EX_NULL_POINTER, "nullPtr");
@@ -229,6 +257,8 @@
             return getParameterBassBoost(id.get<Parameter::Id::bassBoostTag>(), specific);
         case Parameter::Id::virtualizerTag:
             return getParameterVirtualizer(id.get<Parameter::Id::virtualizerTag>(), specific);
+        case Parameter::Id::volumeTag:
+            return getParameterVolume(id.get<Parameter::Id::volumeTag>(), specific);
         default:
             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
@@ -288,6 +318,34 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus EffectBundleAidl::getParameterVolume(const Volume::Id& id,
+                                                        Parameter::Specific* specific) {
+    RETURN_IF(id.getTag() != Volume::Id::commonTag, EX_ILLEGAL_ARGUMENT, "VolumeTagNotSupported");
+
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    Volume volParam;
+
+    auto tag = id.get<Volume::Id::commonTag>();
+    switch (tag) {
+        case Volume::levelDb: {
+            volParam.set<Volume::levelDb>(mContext->getVolumeLevel());
+            break;
+        }
+        case Volume::mute: {
+            volParam.set<Volume::mute>(mContext->getVolumeMute());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " not handled tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "VolumeTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::volume>(volParam);
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus EffectBundleAidl::getParameterVirtualizer(const Virtualizer::Id& id,
                                                              Parameter::Specific* specific) {
     RETURN_IF(id.getTag() != Virtualizer::Id::commonTag, EX_ILLEGAL_ARGUMENT,
diff --git a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.h b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.h
index ebf100a..0330e5a 100644
--- a/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.h
+++ b/media/libeffects/lvm/wrapper/Aidl/EffectBundleAidl.h
@@ -67,6 +67,8 @@
     ndk::ScopedAStatus setParameterEqualizer(const Parameter::Specific& specific);
     ndk::ScopedAStatus getParameterEqualizer(const Equalizer::Id& id,
                                              Parameter::Specific* specific);
+    ndk::ScopedAStatus setParameterVolume(const Parameter::Specific& specific);
+    ndk::ScopedAStatus getParameterVolume(const Volume::Id& id, Parameter::Specific* specific);
     ndk::ScopedAStatus setParameterVirtualizer(const Parameter::Specific& specific);
     ndk::ScopedAStatus getParameterVirtualizer(const Virtualizer::Id& id,
                                                Parameter::Specific* specific);