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/constructor_magic.h"
17 #include "rtc_base/system/rtc_export.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, // Deprecated
31 kDelayAgnostic, // Deprecated
32 kExperimentalAgc,
33 kExperimentalNs,
34 kBeamforming, // Deprecated
35 kIntelligibility, // Deprecated
36 kEchoCanceller3, // Deprecated
37 kAecRefinedAdaptiveFilter, // Deprecated
38 kLevelControl // Deprecated
39 };
40
41 // Class Config is designed to ease passing a set of options across webrtc code.
42 // Options are identified by typename in order to avoid incorrect casts.
43 //
44 // Usage:
45 // * declaring an option:
46 // struct Algo1_CostFunction {
47 // virtual float cost(int x) const { return x; }
48 // virtual ~Algo1_CostFunction() {}
49 // };
50 //
51 // * accessing an option:
52 // config.Get<Algo1_CostFunction>().cost(value);
53 //
54 // * setting an option:
55 // struct SqrCost : Algo1_CostFunction {
56 // virtual float cost(int x) const { return x*x; }
57 // };
58 // config.Set<Algo1_CostFunction>(new SqrCost());
59 //
60 // Note: This class is thread-compatible (like STL containers).
61 class RTC_EXPORT Config {
62 public:
63 // Returns the option if set or a default constructed one.
64 // Callers that access options too often are encouraged to cache the result.
65 // Returned references are owned by this.
66 //
67 // Requires std::is_default_constructible<T>
68 template <typename T>
69 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>
74 void Set(T* value);
75
76 Config();
77 ~Config();
78
79 private:
80 struct BaseOption {
~BaseOptionBaseOption81 virtual ~BaseOption() {}
82 };
83
84 template <typename T>
85 struct Option : BaseOption {
OptionOption86 explicit Option(T* v) : value(v) {}
~OptionOption87 ~Option() { delete value; }
88 T* value;
89 };
90
91 template <typename T>
identifier()92 static ConfigOptionID identifier() {
93 return T::identifier;
94 }
95
96 // Used to instantiate a default constructed object that doesn't needs to be
97 // owned. This allows Get<T> to be implemented without requiring explicitly
98 // locks.
99 template <typename T>
default_value()100 static const T& default_value() {
101 static const T* const def = new T();
102 return *def;
103 }
104
105 typedef std::map<ConfigOptionID, BaseOption*> OptionMap;
106 OptionMap options_;
107
108 // RTC_DISALLOW_COPY_AND_ASSIGN
109 Config(const Config&);
110 void operator=(const Config&);
111 };
112
113 template <typename T>
Get()114 const T& Config::Get() const {
115 OptionMap::const_iterator it = options_.find(identifier<T>());
116 if (it != options_.end()) {
117 const T* t = static_cast<Option<T>*>(it->second)->value;
118 if (t) {
119 return *t;
120 }
121 }
122 return default_value<T>();
123 }
124
125 template <typename T>
Set(T * value)126 void Config::Set(T* value) {
127 BaseOption*& it = options_[identifier<T>()];
128 delete it;
129 it = new Option<T>(value);
130 }
131 } // namespace webrtc
132
133 #endif // MODULES_AUDIO_PROCESSING_INCLUDE_CONFIG_H_
134