Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e450b488 authored by Vlad Popa's avatar Vlad Popa Committed by Automerger Merge Worker
Browse files

CSD: Add interface for attenuating the MEL am: 58e72dcb

parents 291b8ff5 58e72dcb
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -35,6 +35,19 @@ interface ISoundDose {
     */
    oneway void resetCsd(float currentCsd, in SoundDoseRecord[] records);

    /**
     * Updates the attenuation used for the MEL calculation when the volume is
     * not applied by the audio framework. This can be the case when for example
     * the absolute volume is used for a particular device.
     *
     * @param attenuationDB the attenuation as a negative value in dB that will
     *                      be applied for the internal MEL when computing CSD.
     *                      A value of 0 represents no attenuation for the MELs
     * @param device        the audio_devices_t type for which we will apply the
     *                      attenuation
     */
    oneway void updateAttenuation(float attenuationDB, int device);

    /* -------------------------- Test API methods --------------------------
    /** Get the currently used RS2 value. */
    float getOutputRs2();
+37 −0
Original line number Diff line number Diff line
@@ -64,6 +64,10 @@ sp<audio_utils::MelProcessor> SoundDoseManager::getOrCreateProcessorForDevice(
    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 @@ sp<audio_utils::MelProcessor> SoundDoseManager::getOrCreateProcessorForDevice(
        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 @@ void SoundDoseManager::mapAddressToDeviceId(const AudioDeviceTypeAddr& adt,
    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 @@ void SoundDoseManager::clearMapDeviceIdEntries(audio_port_handle_t deviceId) {
        }
        ++activeDevice;
    }
    mActiveDeviceTypes.erase(deviceId);
}

ndk::ScopedAStatus SoundDoseManager::HalSoundDoseCallback::onMomentaryExposureWarning(
@@ -272,6 +282,15 @@ binder::Status SoundDoseManager::SoundDose::resetCsd(
    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 @@ binder::Status SoundDoseManager::SoundDose::forceComputeCsdOnAllDevices(
    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);
+10 −7
Original line number Diff line number Diff line
@@ -95,9 +95,8 @@ public:
    audio_port_handle_t getIdForAudioDevice(
            const aidl::android::media::audio::common::AudioDevice& audioDevice) const;

    /** Caches mapping between address and device port id. */
    void mapAddressToDeviceId(const AudioDeviceTypeAddr& adt,
                              const audio_port_handle_t deviceId);
    /** Caches mapping between address, device port id and device type. */
    void mapAddressToDeviceId(const AudioDeviceTypeAddr& adt, const audio_port_handle_t deviceId);

    /** Clear all map entries with passed audio_port_handle_t. */
    void clearMapDeviceIdEntries(audio_port_handle_t deviceId);
@@ -133,10 +132,11 @@ private:
        binder::Status setOutputRs2(float value) override;
        binder::Status resetCsd(float currentCsd,
                                const std::vector<media::SoundDoseRecord>& records) override;
        binder::Status getOutputRs2(float* value);
        binder::Status getCsd(float* value);
        binder::Status forceUseFrameworkMel(bool useFrameworkMel);
        binder::Status forceComputeCsdOnAllDevices(bool computeCsdOnAllDevices);
        binder::Status updateAttenuation(float attenuationDB, int device) override;
        binder::Status getOutputRs2(float* value) override;
        binder::Status getCsd(float* value) override;
        binder::Status forceUseFrameworkMel(bool useFrameworkMel) override;
        binder::Status forceComputeCsdOnAllDevices(bool computeCsdOnAllDevices) override;

        wp<SoundDoseManager> mSoundDoseManager;
        const sp<media::ISoundDoseCallback> mSoundDoseCallback;
@@ -163,6 +163,7 @@ private:

    sp<media::ISoundDoseCallback> getSoundDoseCallback() const;

    void updateAttenuation(float attenuationDB, audio_devices_t deviceType);
    void setUseFrameworkMel(bool useFrameworkMel);
    void setComputeCsdOnAllDevices(bool computeCsdOnAllDevices);
    /** Returns the HAL sound dose interface or null if internal MEL computation is used. */
@@ -180,8 +181,10 @@ private:
    // logic for deviceId's that should not report MEL values (e.g.: do not have an active MUSIC
    // or GAME stream).
    std::map<AudioDeviceTypeAddr, audio_port_handle_t> mActiveDevices GUARDED_BY(mLock);
    std::unordered_map<audio_port_handle_t, audio_devices_t> mActiveDeviceTypes GUARDED_BY(mLock);

    float mRs2Value GUARDED_BY(mLock);
    std::unordered_map<audio_devices_t, float> mMelAttenuationDB GUARDED_BY(mLock);

    sp<SoundDose> mSoundDose GUARDED_BY(mLock);

+18 −9
Original line number Diff line number Diff line
@@ -17,11 +17,16 @@
// #define LOG_NDEBUG 0
#define LOG_TAG "SoundDoseManager_tests"

#include <SoundDoseManager.h>

#include <aidl/android/hardware/audio/core/sounddose/BnSoundDose.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <SoundDoseManager.h>
#if !defined(BACKEND_NDK)
#define BACKEND_NDK
#endif
#include <media/AidlConversionCppNdk.h>

namespace android {
namespace {
@@ -199,26 +204,30 @@ TEST_F(SoundDoseManagerTest, OnNewMelValuesFromHalWithNoAddressIllegalArgument)
TEST_F(SoundDoseManagerTest, GetIdReturnsMappedAddress) {
    const std::string address = "testAddress";
    const audio_port_handle_t deviceId = 2;
    const AudioDeviceTypeAddr adt{audio_devices_t{0}, address};
    AudioDevice audioDevice;
    audioDevice.address.set<AudioDeviceAddress::id>(address);
    const audio_devices_t deviceType = AUDIO_DEVICE_OUT_WIRED_HEADSET;
    const AudioDeviceTypeAddr adt{deviceType, address};
    auto audioDevice = aidl::android::legacy2aidl_audio_device_AudioDevice(
            deviceType, address.c_str());
    ASSERT_TRUE(audioDevice.ok());

    mSoundDoseManager->mapAddressToDeviceId(adt, deviceId);

    EXPECT_EQ(deviceId, mSoundDoseManager->getIdForAudioDevice(audioDevice));
    EXPECT_EQ(deviceId, mSoundDoseManager->getIdForAudioDevice(audioDevice.value()));
}

TEST_F(SoundDoseManagerTest, GetAfterClearIdReturnsNone) {
    const std::string address = "testAddress";
    const AudioDeviceTypeAddr adt {audio_devices_t{0}, address};
    const audio_devices_t deviceType = AUDIO_DEVICE_OUT_WIRED_HEADSET;
    const AudioDeviceTypeAddr adt{deviceType, address};
    const audio_port_handle_t deviceId = 2;
    AudioDevice audioDevice;
    audioDevice.address.set<AudioDeviceAddress::id>(address);
    auto audioDevice = aidl::android::legacy2aidl_audio_device_AudioDevice(
            deviceType, address.c_str());
    ASSERT_TRUE(audioDevice.ok());

    mSoundDoseManager->mapAddressToDeviceId(adt, deviceId);
    mSoundDoseManager->clearMapDeviceIdEntries(deviceId);

    EXPECT_EQ(AUDIO_PORT_HANDLE_NONE, mSoundDoseManager->getIdForAudioDevice(audioDevice));
    EXPECT_EQ(AUDIO_PORT_HANDLE_NONE, mSoundDoseManager->getIdForAudioDevice(audioDevice.value()));
}

TEST_F(SoundDoseManagerTest, GetUnmappedIdReturnsHandleNone) {