Index: webrtc/common_audio/smoothing_filter.cc |
diff --git a/webrtc/common_audio/smoothing_filter.cc b/webrtc/common_audio/smoothing_filter.cc |
index ff79ab8799e9de332ff324152e97c43947837e6a..11e97dbeee7101f73915ce5fef975f87fd84509a 100644 |
--- a/webrtc/common_audio/smoothing_filter.cc |
+++ b/webrtc/common_audio/smoothing_filter.cc |
@@ -8,60 +8,76 @@ |
* be found in the AUTHORS file in the root of the source tree. |
*/ |
+#include "webrtc/common_audio/smoothing_filter.h" |
+ |
#include <cmath> |
-#include "webrtc/common_audio/smoothing_filter.h" |
+#include "webrtc/base/logging.h" |
namespace webrtc { |
-SmoothingFilterImpl::SmoothingFilterImpl(int time_constant_ms, |
+SmoothingFilterImpl::SmoothingFilterImpl(int init_time_constant_ms_, |
const Clock* clock) |
- : time_constant_ms_(time_constant_ms), |
+ : init_time_constant_ms_(init_time_constant_ms_), |
clock_(clock), |
- first_sample_received_(false), |
- initialized_(false), |
- first_sample_time_ms_(0), |
- last_sample_time_ms_(0), |
- filter_(0.0) {} |
+ initialized_(false) {} |
+ |
+SmoothingFilterImpl::~SmoothingFilterImpl() = default; |
void SmoothingFilterImpl::AddSample(float sample) { |
- if (!first_sample_received_) { |
- last_sample_time_ms_ = first_sample_time_ms_ = clock_->TimeInMilliseconds(); |
- first_sample_received_ = true; |
- RTC_DCHECK_EQ(rtc::ExpFilter::kValueUndefined, filter_.filtered()); |
+ int64_t now_ms = clock_->TimeInMilliseconds(); |
- // Since this is first sample, any value for argument 1 should work. |
- filter_.Apply(0.0f, sample); |
+ if (!first_sample_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; |
+ alpha_ = 0.0f; |
+ first_sample_time_ms_ = rtc::Optional<int64_t>(now_ms); |
+ last_sample_time_ms_ = now_ms; |
return; |
} |
- int64_t now_ms = clock_->TimeInMilliseconds(); |
+ state_ = ExtrapolateLastSample(now_ms); |
+ |
if (!initialized_) { |
michaelt
2016/12/07 09:44:16
Would move this if statement to ExtrapolateLastSam
minyue-webrtc
2016/12/07 17:16:32
It feels weird that GetAverage changes the states.
|
- float duration = now_ms - first_sample_time_ms_; |
- if (duration < static_cast<int64_t>(time_constant_ms_)) { |
- filter_.UpdateBase(exp(1.0f / duration)); |
+ int64_t duration = now_ms - *first_sample_time_ms_; |
+ RTC_DCHECK_GT(duration, 0); |
+ if (duration < init_time_constant_ms_) { |
+ // Use a smaller time constant at the beginning to make it adapt faster. |
+ UpdateAlpha(static_cast<int>(duration)); |
} else { |
initialized_ = true; |
- filter_.UpdateBase(exp(1.0f / time_constant_ms_)); |
+ UpdateAlpha(init_time_constant_ms_); |
} |
} |
- |
- // The filter will do the following: |
- // float alpha = pow(base, last_update_time_ms_ - now_ms); |
- // filtered_ = alpha * filtered_ + (1 - alpha) * sample; |
- filter_.Apply(static_cast<float>(last_sample_time_ms_ - now_ms), sample); |
+ last_sample_ = sample; |
last_sample_time_ms_ = now_ms; |
} |
rtc::Optional<float> SmoothingFilterImpl::GetAverage() const { |
- float value = filter_.filtered(); |
- return value == rtc::ExpFilter::kValueUndefined ? rtc::Optional<float>() |
- : rtc::Optional<float>(value); |
+ if (!first_sample_time_ms_) |
+ return rtc::Optional<float>(); |
+ return rtc::Optional<float>( |
+ ExtrapolateLastSample(clock_->TimeInMilliseconds())); |
} |
void SmoothingFilterImpl::SetTimeConstantMs(int time_constant_ms) { |
- time_constant_ms_ = time_constant_ms; |
- filter_.UpdateBase(exp(1.0f / time_constant_ms_)); |
+ if (!initialized_) { |
michaelt
2016/12/07 09:44:16
would change the impl. of this function to:
init_
minyue-webrtc
2016/12/07 17:16:32
It feels weird that SetTimeConstantMs has two mean
|
+ LOG(LS_INFO) << "SmoothingFilterImpl: Cannot set time constant " |
+ << time_constant_ms << " ms during the initialization time."; |
+ return; |
+ } |
+ UpdateAlpha(time_constant_ms); |
+} |
+ |
+void SmoothingFilterImpl::UpdateAlpha(int time_constant_ms) { |
+ alpha_ = exp(-1.0f / time_constant_ms); |
+} |
+ |
+float SmoothingFilterImpl::ExtrapolateLastSample(int64_t time_ms) const { |
+ RTC_DCHECK_GE(time_ms, last_sample_time_ms_); |
+ float multiplier = pow(alpha_, time_ms - last_sample_time_ms_); |
+ return multiplier * state_ + (1.0f - multiplier) * last_sample_; |
} |
} // namespace webrtc |