CSD: Add interface for attenuating the MEL

The sound dose interface allows to set an attenuation used in the
internal MEL computation. This can be used for example when absolute
volume mode is used.

Test: dumpsys and logs
Bug: 265928284
Change-Id: If1d2c44dd670f9a63249bf7ce6c48e1cc509bcc9
Merged-In: If1d2c44dd670f9a63249bf7ce6c48e1cc509bcc9
diff --git a/services/audioflinger/sounddose/SoundDoseManager.cpp b/services/audioflinger/sounddose/SoundDoseManager.cpp
index 6f9e11f..3dbe8d9 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.cpp
+++ b/services/audioflinger/sounddose/SoundDoseManager.cpp
@@ -64,6 +64,10 @@
     if (streamProcessor != mActiveProcessors.end() &&
             (processor = streamProcessor->second.promote())) {
         ALOGV("%s: found callback for stream %d", __func__, streamHandle);
+        const auto activeTypeIt = mActiveDeviceTypes.find(deviceId);
+        if (activeTypeIt != mActiveDeviceTypes.end()) {
+            processor->setAttenuation(mMelAttenuationDB[activeTypeIt->second]);
+        }
         processor->setDeviceId(deviceId);
         processor->setOutputRs2(mRs2Value);
         return processor;
@@ -71,6 +75,10 @@
         ALOGV("%s: creating new callback for device %d", __func__, streamHandle);
         sp<audio_utils::MelProcessor> melProcessor = sp<audio_utils::MelProcessor>::make(
                 sampleRate, channelCount, format, *this, deviceId, mRs2Value);
+        const auto activeTypeIt = mActiveDeviceTypes.find(deviceId);
+        if (activeTypeIt != mActiveDeviceTypes.end()) {
+            melProcessor->setAttenuation(mMelAttenuationDB[activeTypeIt->second]);
+        }
         mActiveProcessors[streamHandle] = melProcessor;
         return melProcessor;
     }
@@ -174,6 +182,7 @@
     std::lock_guard _l(mLock);
     ALOGI("%s: map address: %s to device id: %d", __func__, adt.toString().c_str(), deviceId);
     mActiveDevices[adt] = deviceId;
+    mActiveDeviceTypes[deviceId] = adt.mType;
 }
 
 void SoundDoseManager::clearMapDeviceIdEntries(audio_port_handle_t deviceId) {
@@ -187,6 +196,7 @@
         }
         ++activeDevice;
     }
+    mActiveDeviceTypes.erase(deviceId);
 }
 
 ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWarning(
@@ -272,6 +282,15 @@
     return binder::Status::ok();
 }
 
+binder::Status SoundDoseManager::SoundDose::updateAttenuation(float attenuationDB, int device) {
+    ALOGV("%s", __func__);
+    auto soundDoseManager = mSoundDoseManager.promote();
+    if (soundDoseManager != nullptr) {
+        soundDoseManager->updateAttenuation(attenuationDB, static_cast<audio_devices_t>(device));
+    }
+    return binder::Status::ok();
+}
+
 binder::Status SoundDoseManager::SoundDose::getOutputRs2(float* value) {
     ALOGV("%s", __func__);
     auto soundDoseManager = mSoundDoseManager.promote();
@@ -310,6 +329,24 @@
     return binder::Status::ok();
 }
 
+void SoundDoseManager::updateAttenuation(float attenuationDB, audio_devices_t deviceType) {
+    std::lock_guard _l(mLock);
+    ALOGV("%s: updating MEL processor attenuation for device %d to %f",
+            __func__, deviceType, attenuationDB);
+    mMelAttenuationDB[deviceType] = attenuationDB;
+    for (const auto& mp : mActiveProcessors) {
+        auto melProcessor = mp.second.promote();
+        if (melProcessor != nullptr) {
+            auto deviceId = melProcessor->getDeviceId();
+            if (mActiveDeviceTypes[deviceId] == deviceType) {
+                ALOGV("%s: updating MEL processor attenuation for deviceId %d to %f",
+                        __func__, deviceId, attenuationDB);
+                melProcessor->setAttenuation(attenuationDB);
+            }
+        }
+    }
+}
+
 void SoundDoseManager::setUseFrameworkMel(bool useFrameworkMel) {
     // invalidate any HAL sound dose interface used
     setHalSoundDoseInterface(nullptr);