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

Commit aaac0fd2 authored by François Gaffie's avatar François Gaffie Committed by Eric Laurent
Browse files

audiopolicy: switch to VolumeGroup for Output



Volume used to be managed per stream type.
VolumeGroup is a configurable way to manage volume affinity.
This CL allows to switch to VolumeGroup as new volume affinity management.

Bug: 124767636
Test: audio smoke tests

Change-Id: I71fc214f6db3158f0f05920cc3d700b29db1a4bc
Signed-off-by: default avatarFrançois Gaffie <francois.gaffie@renault.com>
parent e99551ff
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -16,19 +16,22 @@

#pragma once

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

namespace android {


/**
 * 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
 * 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;
static const VolumeSource VOLUME_SOURCE_NONE = static_cast<VolumeSource>(AUDIO_STREAM_DEFAULT);
enum VolumeSource : std::underlying_type<volume_group_t>::type;
static const VolumeSource VOLUME_SOURCE_NONE = static_cast<VolumeSource>(VOLUME_GROUP_NONE);

static inline VolumeSource streamToVolumeSource(audio_stream_type_t stream) {
    return static_cast<VolumeSource>(stream);
+15 −10
Original line number Diff line number Diff line
@@ -107,7 +107,7 @@ private:
};
/**
 * 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
 */
using VolumeActivities = std::map<VolumeSource, VolumeActivity>;
@@ -157,7 +157,7 @@ public:
    virtual uint32_t latency() { return 0; }
    virtual bool isFixedVolume(audio_devices_t device);
    virtual bool setVolume(float volumeDb,
                           audio_stream_type_t stream,
                           VolumeSource volumeSource, const StreamTypeVector &streams,
                           audio_devices_t device,
                           uint32_t delayMs,
                           bool force);
@@ -221,7 +221,7 @@ public:
    }
    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);
    }
    float getCurVolume(VolumeSource vs) const
@@ -280,6 +280,11 @@ public:
        return mActiveClients;
    }

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

    DeviceVector mDevices; /**< current devices this output is routed to */
    AudioMix *mPolicyMix = nullptr;              // non NULL when used by a dynamic policy

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

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

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

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

bool SwAudioOutputDescriptor::setVolume(float volumeDb,
                                        audio_stream_type_t stream,
                                        VolumeSource vs, const StreamTypeVector &streamTypes,
                                        audio_devices_t device,
                                        uint32_t delayMs,
                                        bool force)
{
    if (!AudioOutputDescriptor::setVolume(volumeDb, stream, device, delayMs, force)) {
    StreamTypeVector streams = streamTypes;
    if (!AudioOutputDescriptor::setVolume(volumeDb, vs, streamTypes, device, delayMs, force)) {
        return false;
    }
    if (streams.empty()) {
        streams.push_back(AUDIO_STREAM_MUSIC);
    }
    if (!devices().isEmpty()) {
        // 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);
        ALOGV("%s: device %s hasGC %d", __FUNCTION__,
            devicePort->toString().c_str(), devices().itemAt(0)->hasGainController(true));
        if (devicePort->hasGainController(true)) {
        if (devicePort->hasGainController(true) && isActive(vs)) {
            ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str());
            // @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?
            float volumeAmpl = Volume::DbToAmpl(0);
            for (const auto &stream : streams) {
                mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
            }

            AudioGains gains = devicePort->getGains();
            int gainMinValueInMb = gains[0]->getMinValueInMb();
@@ -422,11 +434,15 @@ bool SwAudioOutputDescriptor::setVolume(float volumeDb,
        }
    }
    // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
    float volumeAmpl = Volume::DbToAmpl(getCurVolume(static_cast<VolumeSource>(stream)));
    if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
    float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs));
    if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) {
        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);
    }
    return true;
}

@@ -616,12 +632,13 @@ void HwAudioOutputDescriptor::toAudioPort(


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

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

    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;

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

    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);
+2 −0
Original line number Diff line number Diff line
@@ -152,6 +152,8 @@ public:

    volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const;

    volume_group_t getDefaultVolumeGroup() const;

    product_strategy_t getDefault() const;

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