Loading services/audiopolicy/service/AudioPolicyEffects.cpp +47 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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 services/audiopolicy/service/AudioPolicyEffects.h +39 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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 Loading
services/audiopolicy/service/AudioPolicyEffects.cpp +47 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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
services/audiopolicy/service/AudioPolicyEffects.h +39 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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