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/basictypes.h"
17 #include "rtc_base/constructormagic.h"
18
19 namespace webrtc {
20
21 // Only add new values to the end of the enumeration and never remove (only
22 // deprecate) to maintain binary compatibility.
23 enum class ConfigOptionID {
24 kMyExperimentForTest,
25 kAlgo1CostFunctionForTest,
26 kTemporalLayersFactory, // Deprecated
27 kNetEqCapacityConfig, // Deprecated
28 kNetEqFastAccelerate, // Deprecated
29 kVoicePacing, // Deprecated
30 kExtendedFilter,
31 kDelayAgnostic,
32 kExperimentalAgc,
33 kExperimentalNs,
34 kBeamforming,
35 kIntelligibility,
36 kEchoCanceller3, // Deprecated
37 kAecRefinedAdaptiveFilter,
38 kLevelControl,
39 kCaptureDeviceInfo
40 };
41
42 // Class Config is designed to ease passing a set of options across webrtc code.
43 // Options are identified by typename in order to avoid incorrect casts.
44 //
45 // Usage:
46 // * declaring an option:
47 // struct Algo1_CostFunction {
48 // virtual float cost(int x) const { return x; }
49 // virtual ~Algo1_CostFunction() {}
50 // };
51 //
52 // * accessing an option:
53 // config.Get<Algo1_CostFunction>().cost(value);
54 //
55 // * setting an option:
56 // struct SqrCost : Algo1_CostFunction {
57 // virtual float cost(int x) const { return x*x; }
58 // };
59 // config.Set<Algo1_CostFunction>(new SqrCost());
60 //
61 // Note: This class is thread-compatible (like STL containers).
62 class Config {
63 public:
64 // Returns the option if set or a default constructed one.
65 // Callers that access options too often are encouraged to cache the result.
66 // Returned references are owned by this.
67 //
68 // Requires std::is_default_constructible<T>
69 template<typename T> const T& Get() const;
70
71 // Set the option, deleting any previous instance of the same.
72 // This instance gets ownership of the newly set value.
73 template<typename T> 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() {
87 delete value;
88 }
89 T* value;
90 };
91
92 template<typename T>
identifier()93 static ConfigOptionID identifier() {
94 return T::identifier;
95 }
96
97 // Used to instantiate a default constructed object that doesn't needs to be
98 // owned. This allows Get<T> to be implemented without requiring explicitly
99 // locks.
100 template<typename T>
default_value()101 static const T& default_value() {
102 RTC_DEFINE_STATIC_LOCAL(const T, def, ());
103 return def;
104 }
105
106 typedef std::map<ConfigOptionID, BaseOption*> OptionMap;
107 OptionMap options_;
108
109 // RTC_DISALLOW_COPY_AND_ASSIGN
110 Config(const Config&);
111 void operator=(const Config&);
112 };
113
114 template<typename T>
Get()115 const T& Config::Get() const {
116 OptionMap::const_iterator it = options_.find(identifier<T>());
117 if (it != options_.end()) {
118 const T* t = static_cast<Option<T>*>(it->second)->value;
119 if (t) {
120 return *t;
121 }
122 }
123 return default_value<T>();
124 }
125
126 template<typename T>
Set(T * value)127 void Config::Set(T* value) {
128 BaseOption*& it = options_[identifier<T>()];
129 delete it;
130 it = new Option<T>(value);
131 }
132 } // namespace webrtc
133
134 #endif // MODULES_AUDIO_PROCESSING_INCLUDE_CONFIG_H_
135