142aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard/*
242aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * Copyright (C) 2017 The Android Open Source Project
342aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard *
442aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * Licensed under the Apache License, Version 2.0 (the "License");
542aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * you may not use this file except in compliance with the License.
642aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * You may obtain a copy of the License at
742aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard *
842aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard *      http://www.apache.org/licenses/LICENSE-2.0
942aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard *
1042aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * Unless required by applicable law or agreed to in writing, software
1142aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * distributed under the License is distributed on an "AS IS" BASIS,
1242aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1342aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * See the License for the specific language governing permissions and
1442aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * limitations under the License.
1542aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard */
1642aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
1742aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
1842aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard#ifndef ANDROID_MEDIA_EFFECTSCONFIG_H
1942aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard#define ANDROID_MEDIA_EFFECTSCONFIG_H
2042aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
2142aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard/** @file Parses audio effects configuration file to C and C++ structure.
2242aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * @see audio_effects_conf_V2_0.xsd for documentation on each structure
2342aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard */
2442aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
2542aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard#include <system/audio_effect.h>
2642aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
2742aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard#include <map>
2842aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard#include <memory>
2942aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard#include <string>
3042aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard#include <vector>
3142aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
3242aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardnamespace android {
3342aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardnamespace effectsConfig {
3442aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
3542aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard/** Default path of effect configuration file. */
3642aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardconstexpr char DEFAULT_PATH[] = "/vendor/etc/audio_effects.xml";
3742aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
3842aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard/** Directories where the effect libraries will be search for. */
3942aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardconstexpr const char* LD_EFFECT_LIBRARY_PATH[] =
4042aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard#ifdef __LP64__
4142aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard        {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"};
4242aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard#else
4342aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard        {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"};
4442aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard#endif
4542aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
4642aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardstruct Library {
4742aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    std::string name;
4842aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    std::string path;
4942aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard};
5042aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardusing Libraries = std::vector<Library>;
5142aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
5242aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardstruct EffectImpl {
5342aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    Library* library; //< Only valid as long as the associated library vector is unmodified
5442aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    effect_uuid_t uuid;
5542aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard};
5642aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
5742aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardstruct Effect : public EffectImpl {
5842aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    std::string name;
5942aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    bool isProxy;
6042aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    EffectImpl libSw; //< Only valid if isProxy
6142aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    EffectImpl libHw; //< Only valid if isProxy
6242aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard};
6342aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
6442aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardusing Effects = std::vector<Effect>;
6542aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
6642aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardtemplate <class Type>
6742aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardstruct Stream {
6842aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    Type type;
6942aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    std::vector<std::reference_wrapper<Effect>> effects;
7042aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard};
7142aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardusing OutputStream = Stream<audio_stream_type_t>;
7242aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardusing InputStream = Stream<audio_source_t>;
7342aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
7442aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard/** Parsed configuration.
7542aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * Intended to be a transient structure only used for deserialization.
7642aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * Note: Everything is copied in the configuration from the xml dom.
7742aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard *       If copies needed to be avoided due to performance issue,
7842aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard *       consider keeping a private handle on the xml dom and replace all strings by dom pointers.
7942aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard *       Or even better, use SAX parsing to avoid the allocations all together.
8042aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard */
8142aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardstruct Config {
8242aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    float version;
8342aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    Libraries libraries;
8442aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    Effects effects;
8542aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    std::vector<OutputStream> postprocess;
8642aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    std::vector<InputStream> preprocess;
8742aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard};
8842aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
8942aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard/** Result of `parse(const char*)` */
9042aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocardstruct ParsingResult {
9142aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    /** Parsed config, nullptr if the xml lib could not load the file */
9242aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    std::unique_ptr<Config> parsedConfig;
9342aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard    size_t nbSkippedElement; //< Number of skipped invalid library, effect or processing chain
9442aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard};
9542aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
9642aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard/** Parses the provided effect configuration.
9742aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * Parsing do not stop of first invalid element, but continues to the next.
9842aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard * @see ParsingResult::nbSkippedElement
9942aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard */
10042aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin RocardParsingResult parse(const char* path = DEFAULT_PATH);
10142aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard
10242aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard} // namespace effectsConfig
10342aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard} // namespace android
10442aa39a2c6864eeea8e40bd57230ff99ea71be5fKevin Rocard#endif  // ANDROID_MEDIA_EFFECTSCONFIG_H
105