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

Commit cad6c0dd authored by Eric Laurent's avatar Eric Laurent
Browse files

audio policy: add support for virtualizer stage output

Add support for specialized output stream supporting virtualizer stage
effect with headtracking.

The HAL implementation indicates support for this feature with a
specific audio profile with flag AUDIO_OUTPUT_FLAG_VIRTUALIZER_STAGE
listed in the audio policy configuration file.

Note: the flag combination DEEP_BUFFER + FAST is used until a new audio
HAL version is introduced with this flag defined.

The audio policy manager implements methods to query if virtualization
is supported for a particular combination of audio attrbutes, audio
configuration and audio devices.
Methods are also available for the audio policy service to open and close
a specialized virtualization output stream and create the corresponding
audio mixer in audio flinger.

Bug: 188502620
Test: atest audiopolicy_tests

Change-Id: I3b1faf22290775dc7d13953a24098d22cb3790de
parent b3f315a7
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -41,6 +41,42 @@ constexpr bool operator!=(const audio_attributes_t &lhs, const audio_attributes_
    return !(lhs==rhs);
}

constexpr bool operator==(const audio_offload_info_t &lhs, const audio_offload_info_t &rhs)
{
    return lhs.version == rhs.version && lhs.size == rhs.size &&
           lhs.sample_rate == rhs.sample_rate && lhs.channel_mask == rhs.channel_mask &&
           lhs.format == rhs.format && lhs.stream_type == rhs.stream_type &&
           lhs.bit_rate == rhs.bit_rate && lhs.duration_us == rhs.duration_us &&
           lhs.has_video == rhs.has_video && lhs.is_streaming == rhs.is_streaming &&
           lhs.bit_width == rhs.bit_width && lhs.offload_buffer_size == rhs.offload_buffer_size &&
           lhs.usage == rhs.usage && lhs.encapsulation_mode == rhs.encapsulation_mode &&
           lhs.content_id == rhs.content_id && lhs.sync_id == rhs.sync_id;
}
constexpr bool operator!=(const audio_offload_info_t &lhs, const audio_offload_info_t &rhs)
{
    return !(lhs==rhs);
}

constexpr bool operator==(const audio_config_t &lhs, const audio_config_t &rhs)
{
    return lhs.sample_rate == rhs.sample_rate && lhs.channel_mask == rhs.channel_mask &&
           lhs.format == rhs.format && lhs.offload_info == rhs.offload_info;
}
constexpr bool operator!=(const audio_config_t &lhs, const audio_config_t &rhs)
{
    return !(lhs==rhs);
}

constexpr bool operator==(const audio_config_base_t &lhs, const audio_config_base_t &rhs)
{
    return lhs.sample_rate == rhs.sample_rate && lhs.channel_mask == rhs.channel_mask &&
           lhs.format == rhs.format;
}
constexpr bool operator!=(const audio_config_base_t &lhs, const audio_config_base_t &rhs)
{
    return !(lhs==rhs);
}

enum volume_group_t : uint32_t;
static const volume_group_t VOLUME_GROUP_NONE = static_cast<volume_group_t>(-1);

+14 −0
Original line number Diff line number Diff line
@@ -202,6 +202,20 @@ public:
            {AUDIO_FORMAT_AC4, {}}};
    }

    //TODO: b/193496180 use virtualizer stage flag at audio HAL when available
    // until then, use DEEP_BUFFER+FAST flag combo to indicate the virtualizer stage output profile
    void convertVirtualizerStageFlag()
    {
        for (const auto& hwModule : mHwModules) {
            for (const auto& curProfile : hwModule->getOutputProfiles()) {
                if (curProfile->getFlags()
                        == (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
                    curProfile->setFlags(AUDIO_OUTPUT_FLAG_VIRTUALIZER_STAGE);
                }
            }
        }
    }

private:
    static const constexpr char* const kDefaultEngineLibraryNameSuffix = "default";

+4 −0
Original line number Diff line number Diff line
@@ -168,6 +168,10 @@ public:
    DeviceVector getDevicesFromDeviceTypeAddrVec(
            const AudioDeviceTypeAddrVector& deviceTypeAddrVector) const;

    // Return the device vector that contains device descriptor whose AudioDeviceTypeAddr appears
    // in the given AudioDeviceTypeAddrVector
    AudioDeviceTypeAddrVector toTypeAddrVector() const;

    // If there are devices with the given type and the devices to add is not empty,
    // remove all the devices with the given type and add all the devices to add.
    void replaceDevicesByType(audio_devices_t typeToRemove, const DeviceVector &devicesToAdd);
+7 −1
Original line number Diff line number Diff line
@@ -545,6 +545,12 @@ status_t SwAudioOutputDescriptor::open(const audio_config_t *halConfig,

    mFlags = (audio_output_flags_t)(mFlags | flags);

    //TODO: b/193496180 use virtualizer stage flag at audio HAL when available
    audio_output_flags_t halFlags = mFlags;
    if ((mFlags & AUDIO_OUTPUT_FLAG_VIRTUALIZER_STAGE) != 0) {
        halFlags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
    }

    ALOGV("opening output for device %s profile %p name %s",
          mDevices.toString().c_str(), mProfile.get(), mProfile->getName().c_str());

@@ -554,7 +560,7 @@ status_t SwAudioOutputDescriptor::open(const audio_config_t *halConfig,
                                                   &lMixerConfig,
                                                   device,
                                                   &mLatency,
                                                   mFlags);
                                                   halFlags);

    if (status == NO_ERROR) {
        LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
+8 −0
Original line number Diff line number Diff line
@@ -451,6 +451,14 @@ DeviceVector DeviceVector::getDevicesFromDeviceTypeAddrVec(
    return devices;
}

AudioDeviceTypeAddrVector DeviceVector::toTypeAddrVector() const {
    AudioDeviceTypeAddrVector result;
    for (const auto& device : *this) {
        result.push_back(AudioDeviceTypeAddr(device->type(), device->address()));
    }
    return result;
}

void DeviceVector::replaceDevicesByType(
        audio_devices_t typeToRemove, const DeviceVector &devicesToAdd) {
    DeviceVector devicesToRemove = getDevicesFromType(typeToRemove);
Loading