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

Side by Side Diff: webrtc/common_audio/smoothing_filter.cc

Issue 2551363002: Update common_audio/smoothing_filter. (Closed)
Patch Set: fix a comment 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/common_audio/smoothing_filter.h"
12
11 #include <cmath> 13 #include <cmath>
12 14
13 #include "webrtc/common_audio/smoothing_filter.h" 15 #include "webrtc/base/logging.h"
14 16
15 namespace webrtc { 17 namespace webrtc {
16 18
17 SmoothingFilterImpl::SmoothingFilterImpl(int time_constant_ms, 19 SmoothingFilterImpl::SmoothingFilterImpl(int init_time_constant_ms_,
18 const Clock* clock) 20 const Clock* clock)
19 : time_constant_ms_(time_constant_ms), 21 : init_time_constant_ms_(init_time_constant_ms_),
20 clock_(clock), 22 clock_(clock),
21 first_sample_received_(false), 23 initialized_(false) {}
22 initialized_(false), 24
23 first_sample_time_ms_(0), 25 SmoothingFilterImpl::~SmoothingFilterImpl() = default;
24 last_sample_time_ms_(0),
25 filter_(0.0) {}
26 26
27 void SmoothingFilterImpl::AddSample(float sample) { 27 void SmoothingFilterImpl::AddSample(float sample) {
28 if (!first_sample_received_) { 28 int64_t now_ms = clock_->TimeInMilliseconds();
29 last_sample_time_ms_ = first_sample_time_ms_ = clock_->TimeInMilliseconds();
30 first_sample_received_ = true;
31 RTC_DCHECK_EQ(rtc::ExpFilter::kValueUndefined, filter_.filtered());
32 29
33 // Since this is first sample, any value for argument 1 should work. 30 if (!first_sample_time_ms_) {
34 filter_.Apply(0.0f, sample); 31 // This is equivalent to assuming the filter has been receiving the same
32 // value as the first sample since time -infinity.
33 state_ = last_sample_ = sample;
34 alpha_ = 0.0f;
35 first_sample_time_ms_ = rtc::Optional<int64_t>(now_ms);
36 last_sample_time_ms_ = now_ms;
35 return; 37 return;
36 } 38 }
37 39
38 int64_t now_ms = clock_->TimeInMilliseconds(); 40 state_ = ExtrapolateLastSample(now_ms);
41
39 if (!initialized_) { 42 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.
40 float duration = now_ms - first_sample_time_ms_; 43 int64_t duration = now_ms - *first_sample_time_ms_;
41 if (duration < static_cast<int64_t>(time_constant_ms_)) { 44 RTC_DCHECK_GT(duration, 0);
42 filter_.UpdateBase(exp(1.0f / duration)); 45 if (duration < init_time_constant_ms_) {
46 // Use a smaller time constant at the beginning to make it adapt faster.
47 UpdateAlpha(static_cast<int>(duration));
43 } else { 48 } else {
44 initialized_ = true; 49 initialized_ = true;
45 filter_.UpdateBase(exp(1.0f / time_constant_ms_)); 50 UpdateAlpha(init_time_constant_ms_);
46 } 51 }
47 } 52 }
48 53 last_sample_ = sample;
49 // The filter will do the following:
50 // float alpha = pow(base, last_update_time_ms_ - now_ms);
51 // filtered_ = alpha * filtered_ + (1 - alpha) * sample;
52 filter_.Apply(static_cast<float>(last_sample_time_ms_ - now_ms), sample);
53 last_sample_time_ms_ = now_ms; 54 last_sample_time_ms_ = now_ms;
54 } 55 }
55 56
56 rtc::Optional<float> SmoothingFilterImpl::GetAverage() const { 57 rtc::Optional<float> SmoothingFilterImpl::GetAverage() const {
57 float value = filter_.filtered(); 58 if (!first_sample_time_ms_)
58 return value == rtc::ExpFilter::kValueUndefined ? rtc::Optional<float>() 59 return rtc::Optional<float>();
59 : rtc::Optional<float>(value); 60 return rtc::Optional<float>(
61 ExtrapolateLastSample(clock_->TimeInMilliseconds()));
60 } 62 }
61 63
62 void SmoothingFilterImpl::SetTimeConstantMs(int time_constant_ms) { 64 void SmoothingFilterImpl::SetTimeConstantMs(int time_constant_ms) {
63 time_constant_ms_ = time_constant_ms; 65 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
64 filter_.UpdateBase(exp(1.0f / time_constant_ms_)); 66 LOG(LS_INFO) << "SmoothingFilterImpl: Cannot set time constant "
67 << time_constant_ms << " ms during the initialization time.";
68 return;
69 }
70 UpdateAlpha(time_constant_ms);
71 }
72
73 void SmoothingFilterImpl::UpdateAlpha(int time_constant_ms) {
74 alpha_ = exp(-1.0f / time_constant_ms);
75 }
76
77 float SmoothingFilterImpl::ExtrapolateLastSample(int64_t time_ms) const {
78 RTC_DCHECK_GE(time_ms, last_sample_time_ms_);
79 float multiplier = pow(alpha_, time_ms - last_sample_time_ms_);
80 return multiplier * state_ + (1.0f - multiplier) * last_sample_;
65 } 81 }
66 82
67 } // namespace webrtc 83 } // namespace webrtc
OLDNEW
« 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