Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(515)

Unified Diff: webrtc/common_audio/smoothing_filter.cc

Issue 2582043002: Fixing init time error in smoothing filter. (Closed)
Patch Set: on Ivo's comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/common_audio/smoothing_filter.h ('k') | webrtc/common_audio/smoothing_filter_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/common_audio/smoothing_filter.cc
diff --git a/webrtc/common_audio/smoothing_filter.cc b/webrtc/common_audio/smoothing_filter.cc
index d2dde9d8542751d644157bd34e4c671cee177cad..2ab25981f1e3af4b4777026f212591094f75a78c 100644
--- a/webrtc/common_audio/smoothing_filter.cc
+++ b/webrtc/common_audio/smoothing_filter.cc
@@ -14,17 +14,20 @@
namespace webrtc {
-SmoothingFilterImpl::SmoothingFilterImpl(int init_time_ms_, const Clock* clock)
- : init_time_ms_(init_time_ms_),
+SmoothingFilterImpl::SmoothingFilterImpl(int init_time_ms, const Clock* clock)
+ : init_time_ms_(init_time_ms),
// Duing the initalization time, we use an increasing alpha. Specifically,
- // alpha(n) = exp(pow(init_factor_, n)),
+ // alpha(n) = exp(-powf(init_factor_, n)),
// where |init_factor_| is chosen such that
// alpha(init_time_ms_) = exp(-1.0f / init_time_ms_),
- init_factor_(pow(init_time_ms_, 1.0f / init_time_ms_)),
+ init_factor_(init_time_ms_ == 0 ? 0.0f : powf(init_time_ms_,
+ -1.0f / init_time_ms_)),
// |init_const_| is to a factor to help the calculation during
// initialization phase.
- init_const_(1.0f / (init_time_ms_ -
- pow(init_time_ms_, 1.0f - 1.0f / init_time_ms_))),
+ init_const_(init_time_ms_ == 0
+ ? 0.0f
+ : init_time_ms_ -
+ powf(init_time_ms_, 1.0f - 1.0f / init_time_ms_)),
clock_(clock) {
UpdateAlpha(init_time_ms_);
}
@@ -34,11 +37,11 @@ SmoothingFilterImpl::~SmoothingFilterImpl() = default;
void SmoothingFilterImpl::AddSample(float sample) {
const int64_t now_ms = clock_->TimeInMilliseconds();
- if (!first_sample_time_ms_) {
+ if (!init_end_time_ms_) {
// This is equivalent to assuming the filter has been receiving the same
// value as the first sample since time -infinity.
state_ = last_sample_ = sample;
- first_sample_time_ms_ = rtc::Optional<int64_t>(now_ms);
+ init_end_time_ms_ = rtc::Optional<int64_t>(now_ms + init_time_ms_);
last_state_time_ms_ = now_ms;
return;
}
@@ -48,15 +51,16 @@ void SmoothingFilterImpl::AddSample(float sample) {
}
rtc::Optional<float> SmoothingFilterImpl::GetAverage() {
- if (!first_sample_time_ms_)
+ if (!init_end_time_ms_) {
+ // |init_end_time_ms_| undefined since we have not received any sample.
return rtc::Optional<float>();
+ }
ExtrapolateLastSample(clock_->TimeInMilliseconds());
return rtc::Optional<float>(state_);
}
bool SmoothingFilterImpl::SetTimeConstantMs(int time_constant_ms) {
- if (!first_sample_time_ms_ ||
- last_state_time_ms_ < *first_sample_time_ms_ + init_time_ms_) {
+ if (!init_end_time_ms_ || last_state_time_ms_ < *init_end_time_ms_) {
return false;
}
UpdateAlpha(time_constant_ms);
@@ -64,34 +68,43 @@ bool SmoothingFilterImpl::SetTimeConstantMs(int time_constant_ms) {
}
void SmoothingFilterImpl::UpdateAlpha(int time_constant_ms) {
- alpha_ = exp(-1.0f / time_constant_ms);
+ alpha_ = time_constant_ms == 0 ? 0.0f : exp(-1.0f / time_constant_ms);
}
void SmoothingFilterImpl::ExtrapolateLastSample(int64_t time_ms) {
RTC_DCHECK_GE(time_ms, last_state_time_ms_);
- RTC_DCHECK(first_sample_time_ms_);
+ RTC_DCHECK(init_end_time_ms_);
float multiplier = 0.0f;
- if (time_ms <= *first_sample_time_ms_ + init_time_ms_) {
+
+ if (time_ms <= *init_end_time_ms_) {
// Current update is to be made during initialization phase.
// We update the state as if the |alpha| has been increased according
- // alpha(n) = exp(pow(init_factor_, n)),
+ // alpha(n) = exp(-powf(init_factor_, n)),
// where n is the time (in millisecond) since the first sample received.
// With algebraic derivation as shown in the Appendix, we can find that the
// state can be updated in a similar manner as if alpha is a constant,
// except for a different multiplier.
- multiplier = exp(-init_const_ *
- (pow(init_factor_,
- *first_sample_time_ms_ + init_time_ms_ - last_state_time_ms_) -
- pow(init_factor_, *first_sample_time_ms_ + init_time_ms_ - time_ms)));
+ if (init_time_ms_ == 0) {
+ // This means |init_factor_| = 0.
+ multiplier = 0.0f;
+ } else if (init_time_ms_ == 1) {
+ // This means |init_factor_| = 1.
+ multiplier = exp(last_state_time_ms_ - time_ms);
+ } else {
+ multiplier =
+ exp(-(powf(init_factor_, last_state_time_ms_ - *init_end_time_ms_) -
+ powf(init_factor_, time_ms - *init_end_time_ms_)) /
+ init_const_);
+ }
} else {
- if (last_state_time_ms_ < *first_sample_time_ms_ + init_time_ms_) {
+ if (last_state_time_ms_ < *init_end_time_ms_) {
// The latest state update was made during initialization phase.
// We first extrapolate to the initialization time.
- ExtrapolateLastSample(*first_sample_time_ms_ + init_time_ms_);
+ ExtrapolateLastSample(*init_end_time_ms_);
// Then extrapolate the rest by the following.
}
- multiplier = pow(alpha_, time_ms - last_state_time_ms_);
+ multiplier = powf(alpha_, time_ms - last_state_time_ms_);
}
state_ = multiplier * state_ + (1.0f - multiplier) * last_sample_;
@@ -108,17 +121,21 @@ void SmoothingFilterImpl::ExtrapolateLastSample(int64_t time_ms) {
// &= \left(\prod_{i=m}^{n-1} \alpha_i\right) y(m) +
// \left(1 - \prod_{i=m}^{n-1} \alpha_i \right) x(m)
// \end{align}
-// Taking $\alpha_{n} = \exp{\gamma^n}$, $\gamma$ denotes init\_factor\_, the
+// Taking $\alpha_{n} = \exp(-\gamma^n)$, $\gamma$ denotes init\_factor\_, the
// multiplier becomes
// \begin{align}
// \prod_{i=m}^{n-1} \alpha_i
-// &= \exp\left(\prod_{i=m}^{n-1} \gamma^i \right) \\*
-// &= \exp\left(\frac{\gamma^m - \gamma^n}{1 - \gamma} \right)
+// &= \exp\left(-\sum_{i=m}^{n-1} \gamma^i \right) \\*
+// &= \begin{cases}
+// \exp\left(-\frac{\gamma^m - \gamma^n}{1 - \gamma} \right)
+// & \gamma \neq 1 \\*
+// m-n & \gamma = 1
+// \end{cases}
// \end{align}
-// We know $\gamma = T^\frac{1}{T}$, where $T$ denotes init\_time\_ms\_. Then
+// We know $\gamma = T^{-\frac{1}{T}}$, where $T$ denotes init\_time\_ms\_. Then
// $1 - \gamma$ approaches zero when $T$ increases. This can cause numerical
-// difficulties. We multiply $T$ to both numerator and denominator in the
-// fraction. See.
+// difficulties. We multiply $T$ (if $T > 0$) to both numerator and denominator
+// in the fraction. See.
// \begin{align}
// \frac{\gamma^m - \gamma^n}{1 - \gamma}
// &= \frac{T^\frac{T-m}{T} - T^\frac{T-n}{T}}{T - T^{1-\frac{1}{T}}}
« no previous file with comments | « webrtc/common_audio/smoothing_filter.h ('k') | webrtc/common_audio/smoothing_filter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698