OLD | NEW |
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" | 11 #include "webrtc/common_audio/smoothing_filter.h" |
12 | 12 |
13 #include <cmath> | 13 #include <cmath> |
14 | 14 |
| 15 #include "webrtc/base/timeutils.h" |
| 16 |
15 namespace webrtc { | 17 namespace webrtc { |
16 | 18 |
17 SmoothingFilterImpl::SmoothingFilterImpl(int init_time_ms, const Clock* clock) | 19 SmoothingFilterImpl::SmoothingFilterImpl(int init_time_ms) |
18 : init_time_ms_(init_time_ms), | 20 : init_time_ms_(init_time_ms), |
19 // Duing the initalization time, we use an increasing alpha. Specifically, | 21 // Duing the initalization time, we use an increasing alpha. Specifically, |
20 // alpha(n) = exp(-powf(init_factor_, n)), | 22 // alpha(n) = exp(-powf(init_factor_, n)), |
21 // where |init_factor_| is chosen such that | 23 // where |init_factor_| is chosen such that |
22 // alpha(init_time_ms_) = exp(-1.0f / init_time_ms_), | 24 // alpha(init_time_ms_) = exp(-1.0f / init_time_ms_), |
23 init_factor_(init_time_ms_ == 0 ? 0.0f : powf(init_time_ms_, | 25 init_factor_(init_time_ms_ == 0 |
24 -1.0f / init_time_ms_)), | 26 ? 0.0f |
| 27 : powf(init_time_ms_, -1.0f / init_time_ms_)), |
25 // |init_const_| is to a factor to help the calculation during | 28 // |init_const_| is to a factor to help the calculation during |
26 // initialization phase. | 29 // initialization phase. |
27 init_const_(init_time_ms_ == 0 | 30 init_const_(init_time_ms_ == 0 |
28 ? 0.0f | 31 ? 0.0f |
29 : init_time_ms_ - | 32 : init_time_ms_ - |
30 powf(init_time_ms_, 1.0f - 1.0f / init_time_ms_)), | 33 powf(init_time_ms_, 1.0f - 1.0f / init_time_ms_)) { |
31 clock_(clock) { | |
32 UpdateAlpha(init_time_ms_); | 34 UpdateAlpha(init_time_ms_); |
33 } | 35 } |
34 | 36 |
35 SmoothingFilterImpl::~SmoothingFilterImpl() = default; | 37 SmoothingFilterImpl::~SmoothingFilterImpl() = default; |
36 | 38 |
37 void SmoothingFilterImpl::AddSample(float sample) { | 39 void SmoothingFilterImpl::AddSample(float sample) { |
38 const int64_t now_ms = clock_->TimeInMilliseconds(); | 40 const int64_t now_ms = rtc::TimeMillis(); |
39 | 41 |
40 if (!init_end_time_ms_) { | 42 if (!init_end_time_ms_) { |
41 // This is equivalent to assuming the filter has been receiving the same | 43 // This is equivalent to assuming the filter has been receiving the same |
42 // value as the first sample since time -infinity. | 44 // value as the first sample since time -infinity. |
43 state_ = last_sample_ = sample; | 45 state_ = last_sample_ = sample; |
44 init_end_time_ms_ = rtc::Optional<int64_t>(now_ms + init_time_ms_); | 46 init_end_time_ms_ = rtc::Optional<int64_t>(now_ms + init_time_ms_); |
45 last_state_time_ms_ = now_ms; | 47 last_state_time_ms_ = now_ms; |
46 return; | 48 return; |
47 } | 49 } |
48 | 50 |
49 ExtrapolateLastSample(now_ms); | 51 ExtrapolateLastSample(now_ms); |
50 last_sample_ = sample; | 52 last_sample_ = sample; |
51 } | 53 } |
52 | 54 |
53 rtc::Optional<float> SmoothingFilterImpl::GetAverage() { | 55 rtc::Optional<float> SmoothingFilterImpl::GetAverage() { |
54 if (!init_end_time_ms_) { | 56 if (!init_end_time_ms_) { |
55 // |init_end_time_ms_| undefined since we have not received any sample. | 57 // |init_end_time_ms_| undefined since we have not received any sample. |
56 return rtc::Optional<float>(); | 58 return rtc::Optional<float>(); |
57 } | 59 } |
58 ExtrapolateLastSample(clock_->TimeInMilliseconds()); | 60 ExtrapolateLastSample(rtc::TimeMillis()); |
59 return rtc::Optional<float>(state_); | 61 return rtc::Optional<float>(state_); |
60 } | 62 } |
61 | 63 |
62 bool SmoothingFilterImpl::SetTimeConstantMs(int time_constant_ms) { | 64 bool SmoothingFilterImpl::SetTimeConstantMs(int time_constant_ms) { |
63 if (!init_end_time_ms_ || last_state_time_ms_ < *init_end_time_ms_) { | 65 if (!init_end_time_ms_ || last_state_time_ms_ < *init_end_time_ms_) { |
64 return false; | 66 return false; |
65 } | 67 } |
66 UpdateAlpha(time_constant_ms); | 68 UpdateAlpha(time_constant_ms); |
67 return true; | 69 return true; |
68 } | 70 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 // \end{cases} | 135 // \end{cases} |
134 // \end{align} | 136 // \end{align} |
135 // We know $\gamma = T^{-\frac{1}{T}}$, where $T$ denotes init\_time\_ms\_. Then | 137 // We know $\gamma = T^{-\frac{1}{T}}$, where $T$ denotes init\_time\_ms\_. Then |
136 // $1 - \gamma$ approaches zero when $T$ increases. This can cause numerical | 138 // $1 - \gamma$ approaches zero when $T$ increases. This can cause numerical |
137 // difficulties. We multiply $T$ (if $T > 0$) to both numerator and denominator | 139 // difficulties. We multiply $T$ (if $T > 0$) to both numerator and denominator |
138 // in the fraction. See. | 140 // in the fraction. See. |
139 // \begin{align} | 141 // \begin{align} |
140 // \frac{\gamma^m - \gamma^n}{1 - \gamma} | 142 // \frac{\gamma^m - \gamma^n}{1 - \gamma} |
141 // &= \frac{T^\frac{T-m}{T} - T^\frac{T-n}{T}}{T - T^{1-\frac{1}{T}}} | 143 // &= \frac{T^\frac{T-m}{T} - T^\frac{T-n}{T}}{T - T^{1-\frac{1}{T}}} |
142 // \end{align} | 144 // \end{align} |
OLD | NEW |