Merge "[AudioPolicyService] Add creation of DeviceEffects"

gugelfrei
Eric Laurent 5 years ago committed by Gerrit Code Review
commit 04feef633b

@ -42,7 +42,10 @@ namespace android {
AudioPolicyEffects::AudioPolicyEffects()
{
status_t loadResult = loadAudioEffectXmlConfig();
if (loadResult < 0) {
if (loadResult == NO_ERROR) {
mDefaultDeviceEffectFuture = std::async(
std::launch::async, &AudioPolicyEffects::initDefaultDeviceEffects, this);
} else if (loadResult < 0) {
ALOGW("Failed to load XML effect configuration, fallback to .conf");
// load automatic audio effect modules
if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
@ -908,8 +911,24 @@ status_t AudioPolicyEffects::loadAudioEffectXmlConfig() {
streams.add(stream.type, effectDescs.release());
}
};
auto loadDeviceProcessingChain = [](auto &processingChain, auto& devicesEffects) {
for (auto& deviceProcess : processingChain) {
auto effectDescs = std::make_unique<EffectDescVector>();
for (auto& effect : deviceProcess.effects) {
effectDescs->mEffects.add(
new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
}
auto deviceEffects = std::make_unique<DeviceEffects>(
std::move(effectDescs), deviceProcess.type, deviceProcess.address);
devicesEffects.emplace(deviceProcess.address, std::move(deviceEffects));
}
};
loadProcessingChain(result.parsedConfig->preprocess, mInputSources);
loadProcessingChain(result.parsedConfig->postprocess, mOutputStreams);
loadDeviceProcessingChain(result.parsedConfig->deviceprocess, mDeviceEffects);
// Casting from ssize_t to status_t is probably safe, there should not be more than 2^31 errors
return result.nbSkippedElement;
}
@ -942,5 +961,32 @@ status_t AudioPolicyEffects::loadAudioEffectConfig(const char *path)
return NO_ERROR;
}
void AudioPolicyEffects::initDefaultDeviceEffects()
{
Mutex::Autolock _l(mLock);
for (const auto& deviceEffectsIter : mDeviceEffects) {
const auto& deviceEffects = deviceEffectsIter.second;
for (const auto& effectDesc : deviceEffects->mEffectDescriptors->mEffects) {
auto fx = std::make_unique<AudioEffect>(
EFFECT_UUID_NULL, String16("android"), &effectDesc->mUuid, 0, nullptr,
nullptr, AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
AudioDeviceTypeAddr{deviceEffects->getDeviceType(),
deviceEffects->getDeviceAddress()});
status_t status = fx->initCheck();
if (status != NO_ERROR && status != ALREADY_EXISTS) {
ALOGE("%s(): failed to create Fx %s on port type=%d address=%s", __func__,
effectDesc->mName, deviceEffects->getDeviceType(),
deviceEffects->getDeviceAddress().c_str());
// fx goes out of scope and strong ref on AudioEffect is released
continue;
}
fx->setEnabled(true);
ALOGV("%s(): create Fx %s added on port type=%d address=%s", __func__,
effectDesc->mName, deviceEffects->getDeviceType(),
deviceEffects->getDeviceAddress().c_str());
deviceEffects->mEffects.push_back(std::move(fx));
}
}
}
} // namespace android

@ -25,6 +25,9 @@
#include <system/audio.h>
#include <utils/Vector.h>
#include <utils/SortedVector.h>
#include <android-base/thread_annotations.h>
#include <future>
namespace android {
@ -104,6 +107,7 @@ public:
status_t removeStreamDefaultEffect(audio_unique_id_t id);
private:
void initDefaultDeviceEffects();
// class to store the description of an effects and its parameters
// as defined in audio_effects.conf
@ -192,6 +196,28 @@ private:
Vector< sp<AudioEffect> >mEffects;
};
/**
* @brief The DeviceEffects class stores the effects associated to a given Device Port.
*/
class DeviceEffects {
public:
explicit DeviceEffects(std::unique_ptr<EffectDescVector> effectDescriptors,
audio_devices_t device, const std::string& address) :
mEffectDescriptors(std::move(effectDescriptors)),
mDeviceType(device), mDeviceAddress(address) {}
/*virtual*/ ~DeviceEffects() = default;
std::vector<std::unique_ptr<AudioEffect>> mEffects;
audio_devices_t getDeviceType() const { return mDeviceType; }
std::string getDeviceAddress() const { return mDeviceAddress; }
const std::unique_ptr<EffectDescVector> mEffectDescriptors;
private:
const audio_devices_t mDeviceType;
const std::string mDeviceAddress;
};
static const char * const kInputSourceNames[AUDIO_SOURCE_CNT -1];
static audio_source_t inputSourceNameToEnum(const char *name);
@ -237,6 +263,19 @@ private:
KeyedVector< audio_stream_type_t, EffectDescVector* > mOutputStreams;
// Automatic output effects are unique for audiosession ID
KeyedVector< audio_session_t, EffectVector* > mOutputSessions;
/**
* @brief mDeviceEffects map of device effects indexed by the device address
*/
std::map<std::string, std::unique_ptr<DeviceEffects>> mDeviceEffects GUARDED_BY(mLock);
/**
* Device Effect initialization must be asynchronous: the audio_policy service parses and init
* effect on first reference. AudioFlinger will handle effect creation and register these
* effect on audio_policy service.
* We must store the reference of the furture garantee real asynchronous operation.
*/
std::future<void> mDefaultDeviceEffectFuture;
};
} // namespace android

Loading…
Cancel
Save