webrtc_m130/webrtc/common.h
peah 0332c2db39 Added support in the AEC for refined filter adaptation.
The following algorithmic functionality was added:
-Add support for an exact regressor power to be computed
 which avoids the issue with the updating of the filter
 sometimes being unstable.
-Lowered the fixed step size of the adaptive filter to 0.05
 which significantly reduces the sensitivity of the
 adaptive filter to near-end noise, nonlinearities,
 doubletalk and the unmodelled echo path tail. It also
 reduces the tracking speed of the adaptive filter but the
 chosen value proved to give a sufficient tradeoff for the
 requirements on the adaptive filter.

To allow the new functionality to be selectively applied the following was done:
-A new Config was added for selectively activating the functionality.
-Functionality was added in the audioprocessing  and echocancellationimpl classes
 for passing the activation of the functionality down to the AEC algorithms.

To make the code for the introduction of the functionality clean,
the following refactoring was done:
-The selection of the step size was moved to a single place.
-The constant for the step size of the adaptive filter in extended filter mode was
 made local.
-The state variable storing the step-size was renamed to a more describing name.

When the new functionality is not activated, the changes
have been tested for bitexactness on Linux.

TBR=minyue@webrtc.org
BUG=webrtc:5778, webrtc:5777

Review URL: https://codereview.webrtc.org/1887003002

Cr-Commit-Position: refs/heads/master@{#12384}
2016-04-15 18:23:36 +00:00

140 lines
3.6 KiB
C++

/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_COMMON_H_
#define WEBRTC_COMMON_H_
#include <map>
#include "webrtc/base/basictypes.h"
namespace webrtc {
// Only add new values to the end of the enumeration and never remove (only
// deprecate) to maintain binary compatibility.
enum class ConfigOptionID {
kMyExperimentForTest,
kAlgo1CostFunctionForTest,
kTemporalLayersFactory,
kNetEqCapacityConfig,
kNetEqFastAccelerate,
kVoicePacing,
kExtendedFilter,
kDelayAgnostic,
kExperimentalAgc,
kExperimentalNs,
kBeamforming,
kIntelligibility,
kEchoCanceller3,
kAecRefinedAdaptiveFilter
};
// Class Config is designed to ease passing a set of options across webrtc code.
// Options are identified by typename in order to avoid incorrect casts.
//
// Usage:
// * declaring an option:
// struct Algo1_CostFunction {
// virtual float cost(int x) const { return x; }
// virtual ~Algo1_CostFunction() {}
// };
//
// * accessing an option:
// config.Get<Algo1_CostFunction>().cost(value);
//
// * setting an option:
// struct SqrCost : Algo1_CostFunction {
// virtual float cost(int x) const { return x*x; }
// };
// config.Set<Algo1_CostFunction>(new SqrCost());
//
// Note: This class is thread-compatible (like STL containers).
class Config {
public:
// Returns the option if set or a default constructed one.
// Callers that access options too often are encouraged to cache the result.
// Returned references are owned by this.
//
// Requires std::is_default_constructible<T>
template<typename T> const T& Get() const;
// Set the option, deleting any previous instance of the same.
// This instance gets ownership of the newly set value.
template<typename T> void Set(T* value);
Config() {}
~Config() {
// Note: this method is inline so webrtc public API depends only
// on the headers.
for (OptionMap::iterator it = options_.begin();
it != options_.end(); ++it) {
delete it->second;
}
}
private:
struct BaseOption {
virtual ~BaseOption() {}
};
template<typename T>
struct Option : BaseOption {
explicit Option(T* v): value(v) {}
~Option() {
delete value;
}
T* value;
};
template<typename T>
static ConfigOptionID identifier() {
return T::identifier;
}
// Used to instantiate a default constructed object that doesn't needs to be
// owned. This allows Get<T> to be implemented without requiring explicitly
// locks.
template<typename T>
static const T& default_value() {
RTC_DEFINE_STATIC_LOCAL(const T, def, ());
return def;
}
typedef std::map<ConfigOptionID, BaseOption*> OptionMap;
OptionMap options_;
// RTC_DISALLOW_COPY_AND_ASSIGN
Config(const Config&);
void operator=(const Config&);
};
template<typename T>
const T& Config::Get() const {
OptionMap::const_iterator it = options_.find(identifier<T>());
if (it != options_.end()) {
const T* t = static_cast<Option<T>*>(it->second)->value;
if (t) {
return *t;
}
}
return default_value<T>();
}
template<typename T>
void Config::Set(T* value) {
BaseOption*& it = options_[identifier<T>()];
delete it;
it = new Option<T>(value);
}
} // namespace webrtc
#endif // WEBRTC_COMMON_H_