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