Use standard containers for audio stuff in audio framework

1. Add SampleRateSet, FormatSet, ChannelMaskSet, FormatVector
using std::vector and std::set in libaudiofoundation.
2. Use SampleRateSet, FormatSet, ChannelMaskSet, FormatVector in
audio framework.

Bug: 135621476
Test: make, CTS for AudioRecord, AudioTrack, AudioManagerTest
Test: play and record audio
Change-Id: Ic04e637bcc6ba9df84c5e7561ec3c03f18a7d242
gugelfrei
jiabin 5 years ago
parent 433e8a2730
commit 06e4bab545

@ -0,0 +1,52 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <set>
#include <vector>
#include <system/audio.h>
namespace android {
using ChannelMaskSet = std::set<audio_channel_mask_t>;
using FormatSet = std::set<audio_format_t>;
using SampleRateSet = std::set<uint32_t>;
using FormatVector = std::vector<audio_format_t>;
static inline ChannelMaskSet asInMask(const ChannelMaskSet& channelMasks) {
ChannelMaskSet inMaskSet;
for (const auto &channel : channelMasks) {
if (audio_channel_mask_out_to_in(channel) != AUDIO_CHANNEL_INVALID) {
inMaskSet.insert(audio_channel_mask_out_to_in(channel));
}
}
return inMaskSet;
}
static inline ChannelMaskSet asOutMask(const ChannelMaskSet& channelMasks) {
ChannelMaskSet outMaskSet;
for (const auto &channel : channelMasks) {
if (audio_channel_mask_in_to_out(channel) != AUDIO_CHANNEL_INVALID) {
outMaskSet.insert(audio_channel_mask_in_to_out(channel));
}
}
return outMaskSet;
}
} // namespace android

@ -17,10 +17,11 @@
#ifndef ANDROID_TYPE_CONVERTER_H_
#define ANDROID_TYPE_CONVERTER_H_
#include <set>
#include <string>
#include <string.h>
#include <vector>
#include <system/audio.h>
#include <utils/Log.h>
#include <utils/Vector.h>
@ -42,37 +43,37 @@ struct DefaultTraits
}
};
template <typename T>
struct VectorTraits
struct SortedVectorTraits
{
typedef T Type;
typedef Vector<Type> Collection;
typedef SortedVector<Type> Collection;
static void add(Collection &collection, Type value)
{
collection.add(value);
}
};
template <typename T>
struct SortedVectorTraits
struct SetTraits
{
typedef T Type;
typedef SortedVector<Type> Collection;
typedef std::set<Type> Collection;
static void add(Collection &collection, Type value)
{
collection.add(value);
collection.insert(value);
}
};
using SampleRateTraits = SortedVectorTraits<uint32_t>;
using SampleRateTraits = SetTraits<uint32_t>;
using DeviceTraits = DefaultTraits<audio_devices_t>;
struct OutputDeviceTraits : public DeviceTraits {};
struct InputDeviceTraits : public DeviceTraits {};
using ChannelTraits = SortedVectorTraits<audio_channel_mask_t>;
using ChannelTraits = SetTraits<audio_channel_mask_t>;
struct OutputChannelTraits : public ChannelTraits {};
struct InputChannelTraits : public ChannelTraits {};
struct ChannelIndexTraits : public ChannelTraits {};
using InputFlagTraits = DefaultTraits<audio_input_flags_t>;
using OutputFlagTraits = DefaultTraits<audio_output_flags_t>;
using FormatTraits = VectorTraits<audio_format_t>;
using FormatTraits = DefaultTraits<audio_format_t>;
using GainModeTraits = DefaultTraits<audio_gain_mode_t>;
using StreamTraits = DefaultTraits<audio_stream_type_t>;
using AudioModeTraits = DefaultTraits<audio_mode_t>;
@ -259,6 +260,7 @@ template <typename T, std::enable_if_t<std::is_same<T, audio_content_type_t>::va
|| std::is_same<T, audio_source_t>::value
|| std::is_same<T, audio_stream_type_t>::value
|| std::is_same<T, audio_usage_t>::value
|| std::is_same<T, audio_format_t>::value
, int> = 0>
static inline std::string toString(const T& value)
{
@ -291,14 +293,6 @@ static inline std::string toString(const audio_devices_t& devices)
return result;
}
// TODO: Remove when FormatTraits uses DefaultTraits.
static inline std::string toString(const audio_format_t& format)
{
std::string result;
return TypeConverter<VectorTraits<audio_format_t>>::toString(format, result)
? result : std::to_string(static_cast<int>(format));
}
static inline std::string toString(const audio_attributes_t& attributes)
{
std::ostringstream result;

@ -110,8 +110,8 @@ public:
// Used to select an audio HAL output stream with a sample format providing the
// less degradation for a given AudioTrack sample format.
static bool isBetterFormatMatch(audio_format_t newFormat,
audio_format_t currentFormat,
audio_format_t targetFormat);
audio_format_t currentFormat,
audio_format_t targetFormat);
static uint32_t formatDistance(audio_format_t format1,
audio_format_t format2);
static const uint32_t kFormatDistanceMax = 4;
@ -143,8 +143,9 @@ public:
AudioGains mGains; // gain controllers
private:
void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelsVector &channelMasks) const;
void pickSamplingRate(uint32_t &rate,const SampleRateVector &samplingRates) const;
void pickChannelMask(audio_channel_mask_t &channelMask,
const ChannelMaskSet &channelMasks) const;
void pickSamplingRate(uint32_t &rate, const SampleRateSet &samplingRates) const;
sp<HwModule> mModule; // audio HW module exposing this I/O stream
String8 mName;

@ -16,55 +16,15 @@
#pragma once
#include <vector>
#include <media/AudioContainers.h>
#include <system/audio.h>
#include <utils/RefBase.h>
#include <utils/SortedVector.h>
#include <utils/String8.h>
#include "policy.h"
namespace android {
typedef SortedVector<uint32_t> SampleRateVector;
typedef Vector<audio_format_t> FormatVector;
template <typename T>
bool operator== (const SortedVector<T> &left, const SortedVector<T> &right)
{
if (left.size() != right.size()) {
return false;
}
for (size_t index = 0; index < right.size(); index++) {
if (left[index] != right[index]) {
return false;
}
}
return true;
}
template <typename T>
bool operator!= (const SortedVector<T> &left, const SortedVector<T> &right)
{
return !(left == right);
}
class ChannelsVector : public SortedVector<audio_channel_mask_t>
{
public:
ChannelsVector() = default;
ChannelsVector(const ChannelsVector&) = default;
ChannelsVector(const SortedVector<audio_channel_mask_t>& sv) :
SortedVector<audio_channel_mask_t>(sv) {}
ChannelsVector& operator=(const ChannelsVector&) = default;
// Applies audio_channel_mask_out_to_in to all elements and returns the result.
ChannelsVector asInMask() const;
// Applies audio_channel_mask_in_to_out to all elements and returns the result.
ChannelsVector asOutMask() const;
};
class AudioProfile : public virtual RefBase
{
public:
@ -72,22 +32,22 @@ public:
AudioProfile(audio_format_t format, audio_channel_mask_t channelMasks, uint32_t samplingRate);
AudioProfile(audio_format_t format,
const ChannelsVector &channelMasks,
const SampleRateVector &samplingRateCollection);
const ChannelMaskSet &channelMasks,
const SampleRateSet &samplingRateCollection);
audio_format_t getFormat() const { return mFormat; }
const ChannelsVector &getChannels() const { return mChannelMasks; }
const SampleRateVector &getSampleRates() const { return mSamplingRates; }
void setChannels(const ChannelsVector &channelMasks);
void setSampleRates(const SampleRateVector &sampleRates);
const ChannelMaskSet &getChannels() const { return mChannelMasks; }
const SampleRateSet &getSampleRates() const { return mSamplingRates; }
void setChannels(const ChannelMaskSet &channelMasks);
void setSampleRates(const SampleRateSet &sampleRates);
void clear();
bool isValid() const { return hasValidFormat() && hasValidRates() && hasValidChannels(); }
bool supportsChannels(audio_channel_mask_t channels) const
{
return mChannelMasks.indexOf(channels) >= 0;
return mChannelMasks.count(channels) != 0;
}
bool supportsRate(uint32_t rate) const { return mSamplingRates.indexOf(rate) >= 0; }
bool supportsRate(uint32_t rate) const { return mSamplingRates.count(rate) != 0; }
status_t checkExact(uint32_t rate, audio_channel_mask_t channels, audio_format_t format) const;
status_t checkCompatibleChannelMask(audio_channel_mask_t channelMask,
@ -98,8 +58,8 @@ public:
uint32_t &updatedSamplingRate) const;
bool hasValidFormat() const { return mFormat != AUDIO_FORMAT_DEFAULT; }
bool hasValidRates() const { return !mSamplingRates.isEmpty(); }
bool hasValidChannels() const { return !mChannelMasks.isEmpty(); }
bool hasValidRates() const { return !mSamplingRates.empty(); }
bool hasValidChannels() const { return !mChannelMasks.empty(); }
void setDynamicChannels(bool dynamic) { mIsDynamicChannels = dynamic; }
bool isDynamicChannels() const { return mIsDynamicChannels; }
@ -117,8 +77,8 @@ public:
private:
String8 mName;
audio_format_t mFormat;
ChannelsVector mChannelMasks;
SampleRateVector mSamplingRates;
ChannelMaskSet mChannelMasks;
SampleRateSet mSamplingRates;
bool mIsDynamicFormat = false;
bool mIsDynamicChannels = false;
@ -126,13 +86,16 @@ private:
};
class AudioProfileVector : public Vector<sp<AudioProfile> >
class AudioProfileVector : public std::vector<sp<AudioProfile> >
{
public:
ssize_t add(const sp<AudioProfile> &profile);
// This API is intended to be used by the policy manager once retrieving capabilities
// for a profile with dynamic format, rate and channels attributes
ssize_t addProfileFromHal(const sp<AudioProfile> &profileToAdd);
void appendProfiles(const AudioProfileVector& audioProfiles) {
insert(end(), audioProfiles.begin(), audioProfiles.end());
}
status_t checkExactProfile(uint32_t samplingRate, audio_channel_mask_t channelMask,
audio_format_t format) const;
@ -169,10 +132,8 @@ public:
private:
sp<AudioProfile> getProfileFor(audio_format_t format) const;
void setSampleRatesFor(const SampleRateVector &sampleRates, audio_format_t format);
void setChannelsFor(const ChannelsVector &channelMasks, audio_format_t format);
static int compareFormats(const sp<AudioProfile> *profile1, const sp<AudioProfile> *profile2);
void setSampleRatesFor(const SampleRateSet &sampleRates, audio_format_t format);
void setChannelsFor(const ChannelMaskSet &channelMasks, audio_format_t format);
};
bool operator == (const AudioProfile &left, const AudioProfile &right);

@ -64,30 +64,19 @@ void AudioPort::toAudioPort(struct audio_port *port) const
{
// TODO: update this function once audio_port structure reflects the new profile definition.
// For compatibility reason: flatening the AudioProfile into audio_port structure.
SortedVector<audio_format_t> flatenedFormats;
SampleRateVector flatenedRates;
ChannelsVector flatenedChannels;
FormatSet flatenedFormats;
SampleRateSet flatenedRates;
ChannelMaskSet flatenedChannels;
for (const auto& profile : mProfiles) {
if (profile->isValid()) {
audio_format_t formatToExport = profile->getFormat();
const SampleRateVector &ratesToExport = profile->getSampleRates();
const ChannelsVector &channelsToExport = profile->getChannels();
const SampleRateSet &ratesToExport = profile->getSampleRates();
const ChannelMaskSet &channelsToExport = profile->getChannels();
flatenedFormats.insert(formatToExport);
flatenedRates.insert(ratesToExport.begin(), ratesToExport.end());
flatenedChannels.insert(channelsToExport.begin(), channelsToExport.end());
if (flatenedFormats.indexOf(formatToExport) < 0) {
flatenedFormats.add(formatToExport);
}
for (size_t rateIndex = 0; rateIndex < ratesToExport.size(); rateIndex++) {
uint32_t rate = ratesToExport[rateIndex];
if (flatenedRates.indexOf(rate) < 0) {
flatenedRates.add(rate);
}
}
for (size_t chanIndex = 0; chanIndex < channelsToExport.size(); chanIndex++) {
audio_channel_mask_t channels = channelsToExport[chanIndex];
if (flatenedChannels.indexOf(channels) < 0) {
flatenedChannels.add(channels);
}
}
if (flatenedRates.size() > AUDIO_PORT_MAX_SAMPLING_RATES ||
flatenedChannels.size() > AUDIO_PORT_MAX_CHANNEL_MASKS ||
flatenedFormats.size() > AUDIO_PORT_MAX_FORMATS) {
@ -102,23 +91,16 @@ void AudioPort::toAudioPort(struct audio_port *port) const
port->num_sample_rates = flatenedRates.size();
port->num_channel_masks = flatenedChannels.size();
port->num_formats = flatenedFormats.size();
for (size_t i = 0; i < flatenedRates.size(); i++) {
port->sample_rates[i] = flatenedRates[i];
}
for (size_t i = 0; i < flatenedChannels.size(); i++) {
port->channel_masks[i] = flatenedChannels[i];
}
for (size_t i = 0; i < flatenedFormats.size(); i++) {
port->formats[i] = flatenedFormats[i];
}
std::copy(flatenedRates.begin(), flatenedRates.end(), port->sample_rates);
std::copy(flatenedChannels.begin(), flatenedChannels.end(), port->channel_masks);
std::copy(flatenedFormats.begin(), flatenedFormats.end(), port->formats);
ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size());
uint32_t i;
for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) {
port->num_gains = std::min(mGains.size(), (size_t) AUDIO_PORT_MAX_GAINS);
for (size_t i = 0; i < port->num_gains; i++) {
port->gains[i] = mGains[i]->getGain();
}
port->num_gains = i;
}
void AudioPort::importAudioPort(const sp<AudioPort>& port, bool force __unused)
@ -162,7 +144,7 @@ status_t AudioPort::checkExactAudioProfile(const struct audio_port_config *confi
return status;
}
void AudioPort::pickSamplingRate(uint32_t &pickedRate,const SampleRateVector &samplingRates) const
void AudioPort::pickSamplingRate(uint32_t &pickedRate,const SampleRateSet &samplingRates) const
{
pickedRate = 0;
// For direct outputs, pick minimum sampling rate: this helps ensuring that the
@ -170,9 +152,9 @@ void AudioPort::pickSamplingRate(uint32_t &pickedRate,const SampleRateVector &sa
// sink
if (isDirectOutput()) {
uint32_t samplingRate = UINT_MAX;
for (size_t i = 0; i < samplingRates.size(); i ++) {
if ((samplingRates[i] < samplingRate) && (samplingRates[i] > 0)) {
samplingRate = samplingRates[i];
for (const auto rate : samplingRates) {
if ((rate < samplingRate) && (rate > 0)) {
samplingRate = rate;
}
}
pickedRate = (samplingRate == UINT_MAX) ? 0 : samplingRate;
@ -188,16 +170,16 @@ void AudioPort::pickSamplingRate(uint32_t &pickedRate,const SampleRateVector &sa
// TODO: should mSamplingRates[] be ordered in terms of our preference
// and we return the first (and hence most preferred) match? This is of concern if
// we want to choose 96kHz over 192kHz for USB driver stability or resource constraints.
for (size_t i = 0; i < samplingRates.size(); i ++) {
if ((samplingRates[i] > pickedRate) && (samplingRates[i] <= maxRate)) {
pickedRate = samplingRates[i];
for (const auto rate : samplingRates) {
if ((rate > pickedRate) && (rate <= maxRate)) {
pickedRate = rate;
}
}
}
}
void AudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask,
const ChannelsVector &channelMasks) const
const ChannelMaskSet &channelMasks) const
{
pickedChannelMask = AUDIO_CHANNEL_NONE;
// For direct outputs, pick minimum channel count: this helps ensuring that the
@ -205,15 +187,15 @@ void AudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask,
// sink
if (isDirectOutput()) {
uint32_t channelCount = UINT_MAX;
for (size_t i = 0; i < channelMasks.size(); i ++) {
for (const auto channelMask : channelMasks) {
uint32_t cnlCount;
if (useInputChannelMask()) {
cnlCount = audio_channel_count_from_in_mask(channelMasks[i]);
cnlCount = audio_channel_count_from_in_mask(channelMask);
} else {
cnlCount = audio_channel_count_from_out_mask(channelMasks[i]);
cnlCount = audio_channel_count_from_out_mask(channelMask);
}
if ((cnlCount < channelCount) && (cnlCount > 0)) {
pickedChannelMask = channelMasks[i];
pickedChannelMask = channelMask;
channelCount = cnlCount;
}
}
@ -226,15 +208,15 @@ void AudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask,
if (mType != AUDIO_PORT_TYPE_MIX) {
maxCount = UINT_MAX;
}
for (size_t i = 0; i < channelMasks.size(); i ++) {
for (const auto channelMask : channelMasks) {
uint32_t cnlCount;
if (useInputChannelMask()) {
cnlCount = audio_channel_count_from_in_mask(channelMasks[i]);
cnlCount = audio_channel_count_from_in_mask(channelMask);
} else {
cnlCount = audio_channel_count_from_out_mask(channelMasks[i]);
cnlCount = audio_channel_count_from_out_mask(channelMask);
}
if ((cnlCount > channelCount) && (cnlCount <= maxCount)) {
pickedChannelMask = channelMasks[i];
pickedChannelMask = channelMask;
channelCount = cnlCount;
}
}

@ -21,6 +21,7 @@
#define LOG_TAG "APM::AudioProfile"
//#define LOG_NDEBUG 0
#include <media/AudioContainers.h>
#include <media/AudioResamplerPublic.h>
#include <utils/Errors.h>
@ -31,28 +32,6 @@
namespace android {
ChannelsVector ChannelsVector::asInMask() const
{
ChannelsVector inMaskVector;
for (const auto& channel : *this) {
if (audio_channel_mask_out_to_in(channel) != AUDIO_CHANNEL_INVALID) {
inMaskVector.add(audio_channel_mask_out_to_in(channel));
}
}
return inMaskVector;
}
ChannelsVector ChannelsVector::asOutMask() const
{
ChannelsVector outMaskVector;
for (const auto& channel : *this) {
if (audio_channel_mask_in_to_out(channel) != AUDIO_CHANNEL_INVALID) {
outMaskVector.add(audio_channel_mask_in_to_out(channel));
}
}
return outMaskVector;
}
bool operator == (const AudioProfile &left, const AudioProfile &compareTo)
{
return (left.getFormat() == compareTo.getFormat()) &&
@ -63,7 +42,7 @@ bool operator == (const AudioProfile &left, const AudioProfile &compareTo)
static AudioProfile* createFullDynamicImpl()
{
AudioProfile* dynamicProfile = new AudioProfile(gDynamicFormat,
ChannelsVector(), SampleRateVector());
ChannelMaskSet(), SampleRateSet());
dynamicProfile->setDynamicFormat(true);
dynamicProfile->setDynamicChannels(true);
dynamicProfile->setDynamicRate(true);
@ -83,26 +62,26 @@ AudioProfile::AudioProfile(audio_format_t format,
mName(String8("")),
mFormat(format)
{
mChannelMasks.add(channelMasks);
mSamplingRates.add(samplingRate);
mChannelMasks.insert(channelMasks);
mSamplingRates.insert(samplingRate);
}
AudioProfile::AudioProfile(audio_format_t format,
const ChannelsVector &channelMasks,
const SampleRateVector &samplingRateCollection) :
const ChannelMaskSet &channelMasks,
const SampleRateSet &samplingRateCollection) :
mName(String8("")),
mFormat(format),
mChannelMasks(channelMasks),
mSamplingRates(samplingRateCollection) {}
void AudioProfile::setChannels(const ChannelsVector &channelMasks)
void AudioProfile::setChannels(const ChannelMaskSet &channelMasks)
{
if (mIsDynamicChannels) {
mChannelMasks = channelMasks;
}
}
void AudioProfile::setSampleRates(const SampleRateVector &sampleRates)
void AudioProfile::setSampleRates(const SampleRateSet &sampleRates)
{
if (mIsDynamicRate) {
mSamplingRates = sampleRates;
@ -135,7 +114,7 @@ status_t AudioProfile::checkCompatibleSamplingRate(uint32_t samplingRate,
{
ALOG_ASSERT(samplingRate > 0);
if (mSamplingRates.isEmpty()) {
if (mSamplingRates.empty()) {
updatedSamplingRate = samplingRate;
return NO_ERROR;
}
@ -143,19 +122,18 @@ status_t AudioProfile::checkCompatibleSamplingRate(uint32_t samplingRate,
// Search for the closest supported sampling rate that is above (preferred)
// or below (acceptable) the desired sampling rate, within a permitted ratio.
// The sampling rates are sorted in ascending order.
size_t orderOfDesiredRate = mSamplingRates.orderOf(samplingRate);
auto desiredRate = mSamplingRates.lower_bound(samplingRate);
// Prefer to down-sample from a higher sampling rate, as we get the desired frequency spectrum.
if (orderOfDesiredRate < mSamplingRates.size()) {
uint32_t candidate = mSamplingRates[orderOfDesiredRate];
if (candidate / AUDIO_RESAMPLER_DOWN_RATIO_MAX <= samplingRate) {
updatedSamplingRate = candidate;
if (desiredRate != mSamplingRates.end()) {
if (*desiredRate / AUDIO_RESAMPLER_DOWN_RATIO_MAX <= samplingRate) {
updatedSamplingRate = *desiredRate;
return NO_ERROR;
}
}
// But if we have to up-sample from a lower sampling rate, that's OK.
if (orderOfDesiredRate != 0) {
uint32_t candidate = mSamplingRates[orderOfDesiredRate - 1];
if (desiredRate != mSamplingRates.begin()) {
uint32_t candidate = *(--desiredRate);
if (candidate * AUDIO_RESAMPLER_UP_RATIO_MAX >= samplingRate) {
updatedSamplingRate = candidate;
return NO_ERROR;
@ -170,7 +148,7 @@ status_t AudioProfile::checkCompatibleChannelMask(audio_channel_mask_t channelMa
audio_port_type_t portType,
audio_port_role_t portRole) const
{
if (mChannelMasks.isEmpty()) {
if (mChannelMasks.empty()) {
updatedChannelMask = channelMask;
return NO_ERROR;
}
@ -179,8 +157,7 @@ status_t AudioProfile::checkCompatibleChannelMask(audio_channel_mask_t channelMa
== AUDIO_CHANNEL_REPRESENTATION_INDEX;
const uint32_t channelCount = audio_channel_count_from_in_mask(channelMask);
int bestMatch = 0;
for (size_t i = 0; i < mChannelMasks.size(); i ++) {
audio_channel_mask_t supported = mChannelMasks[i];
for (const auto &supported : mChannelMasks) {
if (supported == channelMask) {
// Exact matches always taken.
updatedChannelMask = channelMask;
@ -270,20 +247,20 @@ void AudioProfile::dump(String8 *dst, int spaces) const
if (FormatConverter::toString(mFormat, formatLiteral)) {
dst->appendFormat("%*s- format: %s\n", spaces, "", formatLiteral.c_str());
}
if (!mSamplingRates.isEmpty()) {
if (!mSamplingRates.empty()) {
dst->appendFormat("%*s- sampling rates:", spaces, "");
for (size_t i = 0; i < mSamplingRates.size(); i++) {
dst->appendFormat("%d", mSamplingRates[i]);
dst->append(i == (mSamplingRates.size() - 1) ? "" : ", ");
for (auto it = mSamplingRates.begin(); it != mSamplingRates.end();) {
dst->appendFormat("%d", *it);
dst->append(++it == mSamplingRates.end() ? "" : ", ");
}
dst->append("\n");
}
if (!mChannelMasks.isEmpty()) {
if (!mChannelMasks.empty()) {
dst->appendFormat("%*s- channel masks:", spaces, "");
for (size_t i = 0; i < mChannelMasks.size(); i++) {
dst->appendFormat("0x%04x", mChannelMasks[i]);
dst->append(i == (mChannelMasks.size() - 1) ? "" : ", ");
for (auto it = mChannelMasks.begin(); it != mChannelMasks.end();) {
dst->appendFormat("0x%04x", *it);
dst->append(++it == mChannelMasks.end() ? "" : ", ");
}
dst->append("\n");
}
@ -291,13 +268,14 @@ void AudioProfile::dump(String8 *dst, int spaces) const
ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
{
ssize_t index = Vector::add(profile);
ssize_t index = size();
push_back(profile);
// we sort from worst to best, so that AUDIO_FORMAT_DEFAULT is always the first entry.
// TODO: compareFormats could be a lambda to convert between pointer-to-format to format:
// [](const audio_format_t *format1, const audio_format_t *format2) {
// return compareFormats(*format1, *format2);
// }
sort(compareFormats);
std::sort(begin(), end(),
[](const sp<AudioProfile> & a, const sp<AudioProfile> & b)
{
return AudioPort::compareFormats(a->getFormat(), b->getFormat()) < 0;
});
return index;
}
@ -309,7 +287,7 @@ ssize_t AudioProfileVector::addProfileFromHal(const sp<AudioProfile> &profileToA
}
if (!profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
FormatVector formats;
formats.add(profileToAdd->getFormat());
formats.push_back(profileToAdd->getFormat());
setFormats(FormatVector(formats));
return 0;
}
@ -323,7 +301,7 @@ ssize_t AudioProfileVector::addProfileFromHal(const sp<AudioProfile> &profileToA
}
// Go through the list of profile to avoid duplicates
for (size_t profileIndex = 0; profileIndex < size(); profileIndex++) {
const sp<AudioProfile> &profile = itemAt(profileIndex);
const sp<AudioProfile> &profile = at(profileIndex);
if (profile->isValid() && profile == profileToAdd) {
// Nothing to do
return profileIndex;
@ -337,7 +315,7 @@ status_t AudioProfileVector::checkExactProfile(uint32_t samplingRate,
audio_channel_mask_t channelMask,
audio_format_t format) const
{
if (isEmpty()) {
if (empty()) {
return NO_ERROR;
}
@ -355,7 +333,7 @@ status_t AudioProfileVector::checkCompatibleProfile(uint32_t &samplingRate,
audio_port_type_t portType,
audio_port_role_t portRole) const
{
if (isEmpty()) {
if (empty()) {
return NO_ERROR;
}
@ -365,7 +343,7 @@ status_t AudioProfileVector::checkCompatibleProfile(uint32_t &samplingRate,
// iterate from best format to worst format (reverse order)
for (ssize_t i = size() - 1; i >= 0 ; --i) {
const sp<AudioProfile> profile = itemAt(i);
const sp<AudioProfile> profile = at(i);
audio_format_t formatToCompare = profile->getFormat();
if (formatToCompare == format ||
(checkInexact
@ -391,13 +369,13 @@ status_t AudioProfileVector::checkCompatibleProfile(uint32_t &samplingRate,
void AudioProfileVector::clearProfiles()
{
for (size_t i = size(); i != 0; ) {
sp<AudioProfile> profile = itemAt(--i);
if (profile->isDynamicFormat() && profile->hasValidFormat()) {
removeAt(i);
continue;
for (auto it = begin(); it != end();) {
if ((*it)->isDynamicFormat() && (*it)->hasValidFormat()) {
it = erase(it);
} else {
(*it)->clear();
++it;
}
profile->clear();
}
}
@ -448,16 +426,16 @@ status_t AudioProfileVector::findBestMatchingOutputConfig(const AudioProfileVect
if (inputProfile == nullptr || outputProfile == nullptr) {
continue;
}
auto channels = intersectFilterAndOrder(inputProfile->getChannels().asOutMask(),
auto channels = intersectFilterAndOrder(asOutMask(inputProfile->getChannels()),
outputProfile->getChannels(), preferredOutputChannels);
if (channels.empty()) {
continue;
}
auto sampleRates = preferHigherSamplingRates ?
intersectAndOrder(inputProfile->getSampleRates(), outputProfile->getSampleRates(),
std::greater<typename SampleRateVector::value_type>()) :
std::greater<typename SampleRateSet::value_type>()) :
intersectAndOrder(inputProfile->getSampleRates(), outputProfile->getSampleRates(),
std::less<typename SampleRateVector::value_type>());
std::less<typename SampleRateSet::value_type>());
if (sampleRates.empty()) {
continue;
}
@ -473,30 +451,30 @@ status_t AudioProfileVector::findBestMatchingOutputConfig(const AudioProfileVect
sp<AudioProfile> AudioProfileVector::getFirstValidProfile() const
{
for (size_t i = 0; i < size(); i++) {
if (itemAt(i)->isValid()) {
return itemAt(i);
for (const auto &profile : *this) {
if (profile->isValid()) {
return profile;
}
}
return 0;
return nullptr;
}
sp<AudioProfile> AudioProfileVector::getFirstValidProfileFor(audio_format_t format) const
{
for (size_t i = 0; i < size(); i++) {
if (itemAt(i)->isValid() && itemAt(i)->getFormat() == format) {
return itemAt(i);
for (const auto &profile : *this) {
if (profile->isValid() && profile->getFormat() == format) {
return profile;
}
}
return 0;
return nullptr;
}
FormatVector AudioProfileVector::getSupportedFormats() const
{
FormatVector supportedFormats;
for (size_t i = 0; i < size(); i++) {
if (itemAt(i)->hasValidFormat()) {
supportedFormats.add(itemAt(i)->getFormat());
for (const auto &profile : *this) {
if (profile->hasValidFormat()) {
supportedFormats.push_back(profile->getFormat());
}
}
return supportedFormats;
@ -504,8 +482,7 @@ FormatVector AudioProfileVector::getSupportedFormats() const
bool AudioProfileVector::hasDynamicChannelsFor(audio_format_t format) const
{
for (size_t i = 0; i < size(); i++) {
sp<AudioProfile> profile = itemAt(i);
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicChannels()) {
return true;
}
@ -515,8 +492,8 @@ bool AudioProfileVector::hasDynamicChannelsFor(audio_format_t format) const
bool AudioProfileVector::hasDynamicProfile() const
{
for (size_t i = 0; i < size(); i++) {
if (itemAt(i)->isDynamic()) {
for (const auto &profile : *this) {
if (profile->isDynamic()) {
return true;
}
}
@ -525,8 +502,7 @@ bool AudioProfileVector::hasDynamicProfile() const
bool AudioProfileVector::hasDynamicRateFor(audio_format_t format) const
{
for (size_t i = 0; i < size(); i++) {
sp<AudioProfile> profile = itemAt(i);
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicRate()) {
return true;
}
@ -541,8 +517,8 @@ void AudioProfileVector::setFormats(const FormatVector &formats)
if (dynamicFormatProfile == 0) {
return;
}
for (size_t i = 0; i < formats.size(); i++) {
sp<AudioProfile> profile = new AudioProfile(formats[i],
for (const auto &format : formats) {
sp<AudioProfile> profile = new AudioProfile(format,
dynamicFormatProfile->getChannels(),
dynamicFormatProfile->getSampleRates());
profile->setDynamicFormat(true);
@ -557,25 +533,24 @@ void AudioProfileVector::dump(String8 *dst, int spaces) const
dst->appendFormat("%*s- Profiles:\n", spaces, "");
for (size_t i = 0; i < size(); i++) {
dst->appendFormat("%*sProfile %zu:", spaces + 4, "", i);
itemAt(i)->dump(dst, spaces + 8);
at(i)->dump(dst, spaces + 8);
}
}
sp<AudioProfile> AudioProfileVector::getProfileFor(audio_format_t format) const
{
for (size_t i = 0; i < size(); i++) {
if (itemAt(i)->getFormat() == format) {
return itemAt(i);
for (const auto &profile : *this) {
if (profile->getFormat() == format) {
return profile;
}
}
return 0;
return nullptr;
}
void AudioProfileVector::setSampleRatesFor(
const SampleRateVector &sampleRates, audio_format_t format)
const SampleRateSet &sampleRates, audio_format_t format)
{
for (size_t i = 0; i < size(); i++) {
sp<AudioProfile> profile = itemAt(i);
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicRate()) {
if (profile->hasValidRates()) {
// Need to create a new profile with same format
@ -591,10 +566,9 @@ void AudioProfileVector::setSampleRatesFor(
}
}
void AudioProfileVector::setChannelsFor(const ChannelsVector &channelMasks, audio_format_t format)
void AudioProfileVector::setChannelsFor(const ChannelMaskSet &channelMasks, audio_format_t format)
{
for (size_t i = 0; i < size(); i++) {
sp<AudioProfile> profile = itemAt(i);
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicChannels()) {
if (profile->hasValidChannels()) {
// Need to create a new profile with same format
@ -610,11 +584,4 @@ void AudioProfileVector::setChannelsFor(const ChannelsVector &channelMasks, audi
}
}
// static
int AudioProfileVector::compareFormats(const sp<AudioProfile> *profile1,
const sp<AudioProfile> *profile2)
{
return AudioPort::compareFormats((*profile1)->getFormat(), (*profile2)->getFormat());
}
} // namespace android

@ -47,9 +47,9 @@ DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &enc
* For now, the workaround to remove AC3 and IEC61937 support on HDMI is to declare
* something like 'encodedFormats="AUDIO_FORMAT_PCM_16_BIT"' on the HDMI devicePort.
*/
if (type == AUDIO_DEVICE_OUT_HDMI && mEncodedFormats.isEmpty()) {
mEncodedFormats.add(AUDIO_FORMAT_AC3);
mEncodedFormats.add(AUDIO_FORMAT_IEC61937);
if (type == AUDIO_DEVICE_OUT_HDMI && mEncodedFormats.empty()) {
mEncodedFormats.push_back(AUDIO_FORMAT_AC3);
mEncodedFormats.push_back(AUDIO_FORMAT_IEC61937);
}
}
@ -96,7 +96,7 @@ bool DeviceDescriptor::hasCurrentEncodedFormat() const
if (!device_has_encoding_capability(type())) {
return true;
}
if (mEncodedFormats.isEmpty()) {
if (mEncodedFormats.empty()) {
return true;
}
@ -105,7 +105,7 @@ bool DeviceDescriptor::hasCurrentEncodedFormat() const
bool DeviceDescriptor::supportsFormat(audio_format_t format)
{
if (mEncodedFormats.isEmpty()) {
if (mEncodedFormats.empty()) {
return true;
}

@ -406,8 +406,8 @@ Return<AudioProfileTraits::Element> AudioProfileTraits::deserialize(const xmlNod
samplingRatesFromString(samplingRates, ","));
profile->setDynamicFormat(profile->getFormat() == gDynamicFormat);
profile->setDynamicChannels(profile->getChannels().isEmpty());
profile->setDynamicRate(profile->getSampleRates().isEmpty());
profile->setDynamicChannels(profile->getChannels().empty());
profile->setDynamicRate(profile->getSampleRates().empty());
return profile;
}
@ -437,7 +437,7 @@ Return<MixPortTraits::Element> MixPortTraits::deserialize(const xmlNode *child,
if (status != NO_ERROR) {
return Status::fromStatusT(status);
}
if (profiles.isEmpty()) {
if (profiles.empty()) {
profiles.add(AudioProfile::createFullDynamic());
}
mixPort->setAudioProfiles(profiles);
@ -521,7 +521,7 @@ Return<DevicePortTraits::Element> DevicePortTraits::deserialize(const xmlNode *c
if (status != NO_ERROR) {
return Status::fromStatusT(status);
}
if (profiles.isEmpty()) {
if (profiles.empty()) {
profiles.add(AudioProfile::createFullDynamic());
}
deviceDesc->setAudioProfiles(profiles);

@ -73,6 +73,26 @@ static const std::vector<audio_channel_mask_t> surroundChannelMasksOrder = {{
AUDIO_CHANNEL_OUT_2POINT1POINT2, AUDIO_CHANNEL_OUT_2POINT0POINT2,
AUDIO_CHANNEL_OUT_5POINT1, AUDIO_CHANNEL_OUT_STEREO }};
template <typename T>
bool operator== (const SortedVector<T> &left, const SortedVector<T> &right)
{
if (left.size() != right.size()) {
return false;
}
for (size_t index = 0; index < right.size(); index++) {
if (left[index] != right[index]) {
return false;
}
}
return true;
}
template <typename T>
bool operator!= (const SortedVector<T> &left, const SortedVector<T> &right)
{
return !(left == right);
}
// ----------------------------------------------------------------------------
// AudioPolicyInterface implementation
// ----------------------------------------------------------------------------
@ -1339,13 +1359,13 @@ status_t AudioPolicyManager::getBestMsdAudioProfileFor(const sp<DeviceDescriptor
// Each IOProfile represents a MixPort from audio_policy_configuration.xml
for (const auto &inProfile : inputProfiles) {
if (hwAvSync == ((inProfile->getFlags() & AUDIO_INPUT_FLAG_HW_AV_SYNC) != 0)) {
msdProfiles.appendVector(inProfile->getAudioProfiles());
msdProfiles.appendProfiles(inProfile->getAudioProfiles());
}
}
AudioProfileVector deviceProfiles;
for (const auto &outProfile : outputProfiles) {
if (hwAvSync == ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0)) {
deviceProfiles.appendVector(outProfile->getAudioProfiles());
deviceProfiles.appendProfiles(outProfile->getAudioProfiles());
}
}
struct audio_config_base bestSinkConfig;
@ -6084,24 +6104,24 @@ void AudioPolicyManager::modifySurroundFormats(
formatSet.insert(enforcedSurround.begin(), enforcedSurround.end());
}
for (const auto& format : formatSet) {
formatsPtr->push(format);
formatsPtr->push_back(format);
}
}
void AudioPolicyManager::modifySurroundChannelMasks(ChannelsVector *channelMasksPtr) {
ChannelsVector &channelMasks = *channelMasksPtr;
void AudioPolicyManager::modifySurroundChannelMasks(ChannelMaskSet *channelMasksPtr) {
ChannelMaskSet &channelMasks = *channelMasksPtr;
audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
// If NEVER, then remove support for channelMasks > stereo.
if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
for (size_t maskIndex = 0; maskIndex < channelMasks.size(); ) {
audio_channel_mask_t channelMask = channelMasks[maskIndex];
for (auto it = channelMasks.begin(); it != channelMasks.end();) {
audio_channel_mask_t channelMask = *it;
if (channelMask & ~AUDIO_CHANNEL_OUT_STEREO) {
ALOGI("%s: force NEVER, so remove channelMask 0x%08x", __FUNCTION__, channelMask);
channelMasks.removeAt(maskIndex);
it = channelMasks.erase(it);
} else {
maskIndex++;
++it;
}
}
// If ALWAYS or MANUAL, then make sure we at least support 5.1
@ -6117,7 +6137,7 @@ void AudioPolicyManager::modifySurroundChannelMasks(ChannelsVector *channelMasks
}
// If not then add 5.1 support.
if (!supports5dot1) {
channelMasks.add(AUDIO_CHANNEL_OUT_5POINT1);
channelMasks.insert(AUDIO_CHANNEL_OUT_5POINT1);
ALOGI("%s: force MANUAL or ALWAYS, so adding channelMask for 5.1 surround", __func__);
}
}
@ -6150,8 +6170,8 @@ void AudioPolicyManager::updateAudioProfiles(const sp<DeviceDescriptor>& devDesc
}
for (audio_format_t format : profiles.getSupportedFormats()) {
ChannelsVector channelMasks;
SampleRateVector samplingRates;
ChannelMaskSet channelMasks;
SampleRateSet samplingRates;
AudioParameter requestedParameters;
requestedParameters.addInt(String8(AudioParameter::keyFormat), format);

@ -762,7 +762,7 @@ protected:
private:
// Add or remove AC3 DTS encodings based on user preferences.
void modifySurroundFormats(const sp<DeviceDescriptor>& devDesc, FormatVector *formatsPtr);
void modifySurroundChannelMasks(ChannelsVector *channelMasksPtr);
void modifySurroundChannelMasks(ChannelMaskSet *channelMasksPtr);
// Support for Multi-Stream Decoder (MSD) module
sp<DeviceDescriptor> getMsdAudioInDevice() const;

Loading…
Cancel
Save