1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #ifndef MODULES_AUDIO_PROCESSING_INCLUDE_CONFIG_H_
12 #define MODULES_AUDIO_PROCESSING_INCLUDE_CONFIG_H_
13
14 #include <map>
15
16 #include "rtc_base/system/rtc_export.h"
17
18 namespace webrtc {
19
20 // Only add new values to the end of the enumeration and never remove (only
21 // deprecate) to maintain binary compatibility.
22 enum class ConfigOptionID {
23 kMyExperimentForTest,
24 kAlgo1CostFunctionForTest,
25 kTemporalLayersFactory, // Deprecated
26 kNetEqCapacityConfig, // Deprecated
27 kNetEqFastAccelerate, // Deprecated
28 kVoicePacing, // Deprecated
29 kExtendedFilter, // Deprecated
30 kDelayAgnostic, // Deprecated
31 kExperimentalAgc,
32 kExperimentalNs,
33 kBeamforming, // Deprecated
34 kIntelligibility, // Deprecated
35 kEchoCanceller3, // Deprecated
36 kAecRefinedAdaptiveFilter, // Deprecated
37 kLevelControl // Deprecated
38 };
39
40 // Class Config is designed to ease passing a set of options across webrtc code.
41 // Options are identified by typename in order to avoid incorrect casts.
42 //
43 // Usage:
44 // * declaring an option:
45 // struct Algo1_CostFunction {
46 // virtual float cost(int x) const { return x; }
47 // virtual ~Algo1_CostFunction() {}
48 // };
49 //
50 // * accessing an option:
51 // config.Get<Algo1_CostFunction>().cost(value);
52 //
53 // * setting an option:
54 // struct SqrCost : Algo1_CostFunction {
55 // virtual float cost(int x) const { return x*x; }
56 // };
57 // config.Set<Algo1_CostFunction>(new SqrCost());
58 //
59 // Note: This class is thread-compatible (like STL containers).
60 class RTC_EXPORT Config {
61 public:
62 // Returns the option if set or a default constructed one.
63 // Callers that access options too often are encouraged to cache the result.
64 // Returned references are owned by this.
65 //
66 // Requires std::is_default_constructible<T>
67 template <typename T>
68 const T& Get() const;
69
70 // Set the option, deleting any previous instance of the same.
71 // This instance gets ownership of the newly set value.
72 template <typename T>
73 void Set(T* value);
74
75 Config();
76 ~Config();
77
78 private:
79 struct BaseOption {
~BaseOptionBaseOption80 virtual ~BaseOption() {}
81 };
82
83 template <typename T>
84 struct Option : BaseOption {
OptionOption85 explicit Option(T* v) : value(v) {}
~OptionOption86 ~Option() { delete value; }
87 T* value;
88 };
89
90 template <typename T>
identifier()91 static ConfigOptionID identifier() {
92 return T::identifier;
93 }
94
95 // Used to instantiate a default constructed object that doesn't needs to be
96 // owned. This allows Get<T> to be implemented without requiring explicitly
97 // locks.
98 template <typename T>
default_value()99 static const T& default_value() {
100 static const T* const def = new T();
101 return *def;
102 }
103
104 typedef std::map<ConfigOptionID, BaseOption*> OptionMap;
105 OptionMap options_;
106
107 Config(const Config&);
108 void operator=(const Config&);
109 };
110
111 template <typename T>
Get()112 const T& Config::Get() const {
113 OptionMap::const_iterator it = options_.find(identifier<T>());
114 if (it != options_.end()) {
115 const T* t = static_cast<Option<T>*>(it->second)->value;
116 if (t) {
117 return *t;
118 }
119 }
120 return default_value<T>();
121 }
122
123 template <typename T>
Set(T * value)124 void Config::Set(T* value) {
125 BaseOption*& it = options_[identifier<T>()];
126 delete it;
127 it = new Option<T>(value);
128 }
129 } // namespace webrtc
130
131 #endif // MODULES_AUDIO_PROCESSING_INCLUDE_CONFIG_H_
132