Loading media/libeffects/config/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,8 @@ cc_library { shared_libs: [ "liblog", "libtinyxml2", "libutils", "libmedia_helper", ], header_libs: ["libaudio_system_headers"], Loading media/libeffects/config/include/media/EffectsConfig.h +5 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,10 @@ struct Stream { using OutputStream = Stream<audio_stream_type_t>; using InputStream = Stream<audio_source_t>; struct DeviceEffects : Stream<audio_devices_t> { std::string address; }; /** Parsed configuration. * Intended to be a transient structure only used for deserialization. * Note: Everything is copied in the configuration from the xml dom. Loading @@ -89,6 +93,7 @@ struct Config { Effects effects; std::vector<OutputStream> postprocess; std::vector<InputStream> preprocess; std::vector<DeviceEffects> deviceprocess; }; /** Result of `parse(const char*)` */ Loading media/libeffects/config/src/EffectsConfig.cpp +32 −3 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <log/log.h> #include <media/EffectsConfig.h> #include <media/TypeConverter.h> using namespace tinyxml2; Loading Loading @@ -134,6 +135,11 @@ bool stringToStreamType(const char *streamName, Type* type) return false; } template <> bool stringToStreamType(const char *streamName, audio_devices_t* type) { return deviceFromString(streamName, *type); } /** Parse a library xml note and push the result in libraries or return false on failure. */ bool parseLibrary(const XMLElement& xmlLibrary, Libraries* libraries) { const char* name = xmlLibrary.Attribute("name"); Loading Loading @@ -221,7 +227,7 @@ bool parseEffect(const XMLElement& xmlEffect, Libraries& libraries, Effects* eff return true; } /** Parse an stream from an xml element describing it. /** Parse an <Output|Input>stream or a device from an xml element describing it. * @return true and pushes the stream in streams on success, * false on failure. */ template <class Stream> Loading @@ -233,14 +239,14 @@ bool parseStream(const XMLElement& xmlStream, Effects& effects, std::vector<Stre } Stream stream; if (!stringToStreamType(streamType, &stream.type)) { ALOGE("Invalid stream type %s: %s", streamType, dump(xmlStream)); ALOGE("Invalid <stream|device> type %s: %s", streamType, dump(xmlStream)); return false; } for (auto& xmlApply : getChildren(xmlStream, "apply")) { const char* effectName = xmlApply.get().Attribute("effect"); if (effectName == nullptr) { ALOGE("stream/apply must have reference an effect: %s", dump(xmlApply)); ALOGE("<stream|device>/apply must have reference an effect: %s", dump(xmlApply)); return false; } auto* effect = findByName(effectName, effects); Loading @@ -254,6 +260,21 @@ bool parseStream(const XMLElement& xmlStream, Effects& effects, std::vector<Stre return true; } bool parseDeviceEffects( const XMLElement& xmlDevice, Effects& effects, std::vector<DeviceEffects>* deviceEffects) { const char* address = xmlDevice.Attribute("address"); if (address == nullptr) { ALOGE("device must have an address: %s", dump(xmlDevice)); return false; } if (!parseStream(xmlDevice, effects, deviceEffects)) { return false; } deviceEffects->back().address = address; return true; } /** Internal version of the public parse(const char* path) where path always exist. */ ParsingResult parseWithPath(std::string&& path) { XMLDocument doc; Loading Loading @@ -298,6 +319,14 @@ ParsingResult parseWithPath(std::string&& path) { registerFailure(parseStream(xmlStream, config->effects, &config->postprocess)); } } // Parse device effect chains for (auto& xmlDeviceEffects : getChildren(xmlConfig, "deviceEffects")) { for (auto& xmlDevice : getChildren(xmlDeviceEffects, "devicePort")) { registerFailure( parseDeviceEffects(xmlDevice, config->effects, &config->deviceprocess)); } } } return {std::move(config), nbSkippedElements, std::move(path)}; } Loading media/libeffects/data/audio_effects.xml +27 −0 Original line number Diff line number Diff line Loading @@ -99,4 +99,31 @@ </postprocess> --> <!-- Device pre/post processor configurations. The device pre/post processor configuration is described in a deviceEffects element and consists in a list of elements each describing pre/post proecessor settings for a given device or "devicePort". Each devicePort element has a "type" attribute corresponding to the device type (e.g. speaker, bus), an "address" attribute corresponding to the device address and contains a list of "apply" elements indicating one effect to apply. If the device is a source, only pre processing effects are expected, if the device is a sink, only post processing effects are expected. The effect to apply is designated by its name in the "effects" elements. The effect will be enabled by default and the audio framework will automatically add and activate the effect if the given port is involved in an audio patch. If the patch is "HW", the effect must be HW accelerated. <deviceEffects> <devicePort type="AUDIO_DEVICE_OUT_BUS" address="BUS00_USAGE_MAIN"> <apply effect="equalizer"/> </devicePort> <devicePort type="AUDIO_DEVICE_OUT_BUS" address="BUS04_USAGE_VOICE"> <apply effect="volume"/> </devicePort> <devicePort type="AUDIO_DEVICE_IN_BUILTIN_MIC" address="bottom"> <apply effect="agc"/> </devicePort> </deviceEffects> --> </audio_effects_conf> Loading
media/libeffects/config/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,8 @@ cc_library { shared_libs: [ "liblog", "libtinyxml2", "libutils", "libmedia_helper", ], header_libs: ["libaudio_system_headers"], Loading
media/libeffects/config/include/media/EffectsConfig.h +5 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,10 @@ struct Stream { using OutputStream = Stream<audio_stream_type_t>; using InputStream = Stream<audio_source_t>; struct DeviceEffects : Stream<audio_devices_t> { std::string address; }; /** Parsed configuration. * Intended to be a transient structure only used for deserialization. * Note: Everything is copied in the configuration from the xml dom. Loading @@ -89,6 +93,7 @@ struct Config { Effects effects; std::vector<OutputStream> postprocess; std::vector<InputStream> preprocess; std::vector<DeviceEffects> deviceprocess; }; /** Result of `parse(const char*)` */ Loading
media/libeffects/config/src/EffectsConfig.cpp +32 −3 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <log/log.h> #include <media/EffectsConfig.h> #include <media/TypeConverter.h> using namespace tinyxml2; Loading Loading @@ -134,6 +135,11 @@ bool stringToStreamType(const char *streamName, Type* type) return false; } template <> bool stringToStreamType(const char *streamName, audio_devices_t* type) { return deviceFromString(streamName, *type); } /** Parse a library xml note and push the result in libraries or return false on failure. */ bool parseLibrary(const XMLElement& xmlLibrary, Libraries* libraries) { const char* name = xmlLibrary.Attribute("name"); Loading Loading @@ -221,7 +227,7 @@ bool parseEffect(const XMLElement& xmlEffect, Libraries& libraries, Effects* eff return true; } /** Parse an stream from an xml element describing it. /** Parse an <Output|Input>stream or a device from an xml element describing it. * @return true and pushes the stream in streams on success, * false on failure. */ template <class Stream> Loading @@ -233,14 +239,14 @@ bool parseStream(const XMLElement& xmlStream, Effects& effects, std::vector<Stre } Stream stream; if (!stringToStreamType(streamType, &stream.type)) { ALOGE("Invalid stream type %s: %s", streamType, dump(xmlStream)); ALOGE("Invalid <stream|device> type %s: %s", streamType, dump(xmlStream)); return false; } for (auto& xmlApply : getChildren(xmlStream, "apply")) { const char* effectName = xmlApply.get().Attribute("effect"); if (effectName == nullptr) { ALOGE("stream/apply must have reference an effect: %s", dump(xmlApply)); ALOGE("<stream|device>/apply must have reference an effect: %s", dump(xmlApply)); return false; } auto* effect = findByName(effectName, effects); Loading @@ -254,6 +260,21 @@ bool parseStream(const XMLElement& xmlStream, Effects& effects, std::vector<Stre return true; } bool parseDeviceEffects( const XMLElement& xmlDevice, Effects& effects, std::vector<DeviceEffects>* deviceEffects) { const char* address = xmlDevice.Attribute("address"); if (address == nullptr) { ALOGE("device must have an address: %s", dump(xmlDevice)); return false; } if (!parseStream(xmlDevice, effects, deviceEffects)) { return false; } deviceEffects->back().address = address; return true; } /** Internal version of the public parse(const char* path) where path always exist. */ ParsingResult parseWithPath(std::string&& path) { XMLDocument doc; Loading Loading @@ -298,6 +319,14 @@ ParsingResult parseWithPath(std::string&& path) { registerFailure(parseStream(xmlStream, config->effects, &config->postprocess)); } } // Parse device effect chains for (auto& xmlDeviceEffects : getChildren(xmlConfig, "deviceEffects")) { for (auto& xmlDevice : getChildren(xmlDeviceEffects, "devicePort")) { registerFailure( parseDeviceEffects(xmlDevice, config->effects, &config->deviceprocess)); } } } return {std::move(config), nbSkippedElements, std::move(path)}; } Loading
media/libeffects/data/audio_effects.xml +27 −0 Original line number Diff line number Diff line Loading @@ -99,4 +99,31 @@ </postprocess> --> <!-- Device pre/post processor configurations. The device pre/post processor configuration is described in a deviceEffects element and consists in a list of elements each describing pre/post proecessor settings for a given device or "devicePort". Each devicePort element has a "type" attribute corresponding to the device type (e.g. speaker, bus), an "address" attribute corresponding to the device address and contains a list of "apply" elements indicating one effect to apply. If the device is a source, only pre processing effects are expected, if the device is a sink, only post processing effects are expected. The effect to apply is designated by its name in the "effects" elements. The effect will be enabled by default and the audio framework will automatically add and activate the effect if the given port is involved in an audio patch. If the patch is "HW", the effect must be HW accelerated. <deviceEffects> <devicePort type="AUDIO_DEVICE_OUT_BUS" address="BUS00_USAGE_MAIN"> <apply effect="equalizer"/> </devicePort> <devicePort type="AUDIO_DEVICE_OUT_BUS" address="BUS04_USAGE_VOICE"> <apply effect="volume"/> </devicePort> <devicePort type="AUDIO_DEVICE_IN_BUILTIN_MIC" address="bottom"> <apply effect="agc"/> </devicePort> </deviceEffects> --> </audio_effects_conf>