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

Commit b3527ddc authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "audiopolicy: switch to VolumeGroup for Output"

parents 3e75e2b7 aaac0fd2
Loading
Loading
Loading
Loading
+6 −3
Original line number Original line Diff line number Diff line
@@ -16,19 +16,22 @@


#pragma once
#pragma once


#include <media/AudioCommonTypes.h>
#include <system/audio.h>
#include <system/audio.h>
#include <utils/Log.h>
#include <utils/Log.h>
#include <math.h>
#include <math.h>


namespace android {
namespace android {



/**
/**
 * VolumeSource is the discriminent for volume management on an output.
 * VolumeSource is the discriminent for volume management on an output.
 * It used to be the stream type by legacy, it may be host volume group or a volume curves if
 * It used to be the stream type by legacy, it may be host volume group or a volume curves if
 * we allow to have more than one curve per volume group.
 * we allow to have more than one curve per volume group (mandatory to get rid of AudioServer
 * stream aliases.
 */
 */
enum VolumeSource : std::underlying_type<audio_stream_type_t>::type;
enum VolumeSource : std::underlying_type<volume_group_t>::type;
static const VolumeSource VOLUME_SOURCE_NONE = static_cast<VolumeSource>(AUDIO_STREAM_DEFAULT);
static const VolumeSource VOLUME_SOURCE_NONE = static_cast<VolumeSource>(VOLUME_GROUP_NONE);


static inline VolumeSource streamToVolumeSource(audio_stream_type_t stream) {
static inline VolumeSource streamToVolumeSource(audio_stream_type_t stream) {
    return static_cast<VolumeSource>(stream);
    return static_cast<VolumeSource>(stream);
+15 −10
Original line number Original line Diff line number Diff line
@@ -107,7 +107,7 @@ private:
};
};
/**
/**
 * Note: volume activities shall be indexed by CurvesId if we want to allow multiple
 * Note: volume activities shall be indexed by CurvesId if we want to allow multiple
 * curves per volume group, inferring a mute management or volume balancing between HW and SW is
 * curves per volume source, inferring a mute management or volume balancing between HW and SW is
 * done
 * done
 */
 */
using VolumeActivities = std::map<VolumeSource, VolumeActivity>;
using VolumeActivities = std::map<VolumeSource, VolumeActivity>;
@@ -157,7 +157,7 @@ public:
    virtual uint32_t latency() { return 0; }
    virtual uint32_t latency() { return 0; }
    virtual bool isFixedVolume(audio_devices_t device);
    virtual bool isFixedVolume(audio_devices_t device);
    virtual bool setVolume(float volumeDb,
    virtual bool setVolume(float volumeDb,
                           audio_stream_type_t stream,
                           VolumeSource volumeSource, const StreamTypeVector &streams,
                           audio_devices_t device,
                           audio_devices_t device,
                           uint32_t delayMs,
                           uint32_t delayMs,
                           bool force);
                           bool force);
@@ -221,7 +221,7 @@ public:
    }
    }
    void setCurVolume(VolumeSource vs, float volumeDb)
    void setCurVolume(VolumeSource vs, float volumeDb)
    {
    {
        // Even if not activity for this group registered, need to create anyway
        // Even if not activity for this source registered, need to create anyway
        mVolumeActivities[vs].setVolume(volumeDb);
        mVolumeActivities[vs].setVolume(volumeDb);
    }
    }
    float getCurVolume(VolumeSource vs) const
    float getCurVolume(VolumeSource vs) const
@@ -280,6 +280,11 @@ public:
        return mActiveClients;
        return mActiveClients;
    }
    }


    bool useHwGain() const
    {
        return !devices().isEmpty() ? devices().itemAt(0)->hasGainController() : false;
    }

    DeviceVector mDevices; /**< current devices this output is routed to */
    DeviceVector mDevices; /**< current devices this output is routed to */
    wp<AudioPolicyMix> mPolicyMix;  // non NULL when used by a dynamic policy
    wp<AudioPolicyMix> mPolicyMix;  // non NULL when used by a dynamic policy


@@ -328,7 +333,7 @@ public:
        }
        }
    }
    }
    virtual bool setVolume(float volumeDb,
    virtual bool setVolume(float volumeDb,
                           audio_stream_type_t stream,
                           VolumeSource volumeSource, const StreamTypeVector &streams,
                           audio_devices_t device,
                           audio_devices_t device,
                           uint32_t delayMs,
                           uint32_t delayMs,
                           bool force);
                           bool force);
@@ -402,7 +407,7 @@ public:
            void dump(String8 *dst) const override;
            void dump(String8 *dst) const override;


    virtual bool setVolume(float volumeDb,
    virtual bool setVolume(float volumeDb,
                           audio_stream_type_t stream,
                           VolumeSource volumeSource, const StreamTypeVector &streams,
                           audio_devices_t device,
                           audio_devices_t device,
                           uint32_t delayMs,
                           uint32_t delayMs,
                           bool force);
                           bool force);
@@ -488,8 +493,8 @@ public:
    /**
    /**
     * @brief isAnyOutputActive checks if any output is active (aka playing) except the one(s) that
     * @brief isAnyOutputActive checks if any output is active (aka playing) except the one(s) that
     * hold the volume source to be ignored
     * hold the volume source to be ignored
     * @param volumeSourceToIgnore source not considered in the activity detection
     * @param volumeSourceToIgnore source not to be considered in the activity detection
     * @return true if any output is active for any source except the one to be ignored
     * @return true if any output is active for any volume source except the one to be ignored
     */
     */
    bool isAnyOutputActive(VolumeSource volumeSourceToIgnore) const
    bool isAnyOutputActive(VolumeSource volumeSourceToIgnore) const
    {
    {
@@ -518,8 +523,8 @@ public:
    /**
    /**
     * @brief isAnyOutputActive checks if any output is active (aka playing) except the one(s) that
     * @brief isAnyOutputActive checks if any output is active (aka playing) except the one(s) that
     * hold the volume source to be ignored
     * hold the volume source to be ignored
     * @param volumeSourceToIgnore source not considered in the activity detection
     * @param volumeSourceToIgnore source not to be considered in the activity detection
     * @return true if any output is active for any source except the one to be ignored
     * @return true if any output is active for any volume source except the one to be ignored
     */
     */
    bool isAnyOutputActive(VolumeSource volumeSourceToIgnore) const
    bool isAnyOutputActive(VolumeSource volumeSourceToIgnore) const
    {
    {
+33 −16
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@
#include "AudioGain.h"
#include "AudioGain.h"
#include "Volume.h"
#include "Volume.h"
#include "HwModule.h"
#include "HwModule.h"
#include "TypeConverter.h"
#include <media/AudioParameter.h>
#include <media/AudioParameter.h>
#include <media/AudioPolicy.h>
#include <media/AudioPolicy.h>


@@ -152,17 +153,18 @@ bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
}
}


bool AudioOutputDescriptor::setVolume(float volumeDb,
bool AudioOutputDescriptor::setVolume(float volumeDb,
                                      audio_stream_type_t stream,
                                      VolumeSource volumeSource,
                                      audio_devices_t device __unused,
                                      const StreamTypeVector &/*streams*/,
                                      audio_devices_t /*device*/,
                                      uint32_t delayMs,
                                      uint32_t delayMs,
                                      bool force)
                                      bool force)
{
{
    // We actually change the volume if:
    // We actually change the volume if:
    // - the float value returned by computeVolume() changed
    // - the float value returned by computeVolume() changed
    // - the force flag is set
    // - the force flag is set
    if (volumeDb != getCurVolume(static_cast<VolumeSource>(stream)) || force) {
    if (volumeDb != getCurVolume(volumeSource) || force) {
        ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volumeDb, delayMs);
        ALOGV("%s for volumeSrc %d, volume %f, delay %d", __func__, volumeSource, volumeDb, delayMs);
        setCurVolume(static_cast<VolumeSource>(stream), volumeDb);
        setCurVolume(volumeSource, volumeDb);
        return true;
        return true;
    }
    }
    return false;
    return false;
@@ -391,23 +393,33 @@ void SwAudioOutputDescriptor::toAudioPort(
}
}


bool SwAudioOutputDescriptor::setVolume(float volumeDb,
bool SwAudioOutputDescriptor::setVolume(float volumeDb,
                                        audio_stream_type_t stream,
                                        VolumeSource vs, const StreamTypeVector &streamTypes,
                                        audio_devices_t device,
                                        audio_devices_t device,
                                        uint32_t delayMs,
                                        uint32_t delayMs,
                                        bool force)
                                        bool force)
{
{
    if (!AudioOutputDescriptor::setVolume(volumeDb, stream, device, delayMs, force)) {
    StreamTypeVector streams = streamTypes;
    if (!AudioOutputDescriptor::setVolume(volumeDb, vs, streamTypes, device, delayMs, force)) {
        return false;
        return false;
    }
    }
    if (streams.empty()) {
        streams.push_back(AUDIO_STREAM_MUSIC);
    }
    if (!devices().isEmpty()) {
    if (!devices().isEmpty()) {
        // Assume first device to check upon Gain Crontroller availability
        // Assume first device to check upon Gain Crontroller availability
        // APM loops on all group, so filter on active group to set the port gain,
        // let the other groups set the stream volume as per legacy
        const auto &devicePort = devices().itemAt(0);
        const auto &devicePort = devices().itemAt(0);
        ALOGV("%s: device %s hasGC %d", __FUNCTION__,
        if (devicePort->hasGainController(true) && isActive(vs)) {
            devicePort->toString().c_str(), devices().itemAt(0)->hasGainController(true));
            ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str());
        if (devicePort->hasGainController(true)) {
            // @todo: here we might be in trouble if the SwOutput has several active clients with
            // different Volume Source (or if we allow several curves within same volume group)
            //
            // @todo: default stream volume to max (0) when using HW Port gain?
            // @todo: default stream volume to max (0) when using HW Port gain?
            float volumeAmpl = Volume::DbToAmpl(0);
            float volumeAmpl = Volume::DbToAmpl(0);
            for (const auto &stream : streams) {
                mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
                mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
            }


            AudioGains gains = devicePort->getGains();
            AudioGains gains = devicePort->getGains();
            int gainMinValueInMb = gains[0]->getMinValueInMb();
            int gainMinValueInMb = gains[0]->getMinValueInMb();
@@ -424,11 +436,15 @@ bool SwAudioOutputDescriptor::setVolume(float volumeDb,
        }
        }
    }
    }
    // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
    // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
    float volumeAmpl = Volume::DbToAmpl(getCurVolume(static_cast<VolumeSource>(stream)));
    float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs));
    if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
    if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) {
        mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mIoHandle, delayMs);
        mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mIoHandle, delayMs);
    }
    }
    for (const auto &stream : streams) {
        ALOGV("%s output %d for volumeSource %d, volume %f, delay %d stream=%s", __func__,
              mIoHandle, vs, volumeDb, delayMs, toString(stream).c_str());
        mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
        mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
    }
    return true;
    return true;
}
}


@@ -618,12 +634,13 @@ void HwAudioOutputDescriptor::toAudioPort(




bool HwAudioOutputDescriptor::setVolume(float volumeDb,
bool HwAudioOutputDescriptor::setVolume(float volumeDb,
                                        audio_stream_type_t stream,
                                        VolumeSource volumeSource, const StreamTypeVector &streams,
                                        audio_devices_t device,
                                        audio_devices_t device,
                                        uint32_t delayMs,
                                        uint32_t delayMs,
                                        bool force)
                                        bool force)
{
{
    bool changed = AudioOutputDescriptor::setVolume(volumeDb, stream, device, delayMs, force);
    bool changed =
        AudioOutputDescriptor::setVolume(volumeDb, volumeSource, streams, device, delayMs, force);


    if (changed) {
    if (changed) {
      // TODO: use gain controller on source device if any to adjust volume
      // TODO: use gain controller on source device if any to adjust volume
+1 −5
Original line number Original line Diff line number Diff line
@@ -84,10 +84,6 @@ public:


    volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const override;
    volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const override;


    StreamTypeVector getStreamTypesForVolumeGroup(volume_group_t volumeGroup) const override;

    AttributesVector getAllAttributesForVolumeGroup(volume_group_t volumeGroup) const override;

    status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) const override;
    status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) const override;


    void dump(String8 *dst) const override;
    void dump(String8 *dst) const override;
@@ -112,7 +108,7 @@ public:


    VolumeSource toVolumeSource(audio_stream_type_t stream) const
    VolumeSource toVolumeSource(audio_stream_type_t stream) const
    {
    {
        return static_cast<VolumeSource>(stream);
        return static_cast<VolumeSource>(getVolumeGroupForStreamType(stream));
    }
    }


    status_t switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst);
    status_t switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst);
+2 −0
Original line number Original line Diff line number Diff line
@@ -152,6 +152,8 @@ public:


    volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const;
    volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const;


    volume_group_t getDefaultVolumeGroup() const;

    product_strategy_t getDefault() const;
    product_strategy_t getDefault() const;


    void dump(String8 *dst, int spaces = 0) const;
    void dump(String8 *dst, int spaces = 0) const;
Loading