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/base/checks.h" | |
11 #include "webrtc/modules/audio_processing/echo_detector/echo_detector.h" | 12 #include "webrtc/modules/audio_processing/echo_detector/echo_detector.h" |
hlundin-webrtc
2016/10/14 08:00:39
Aways include the corresponding .h file before any
ivoc
2016/10/17 16:05:08
Done.
| |
12 | 13 |
14 #include <math.h> | |
hlundin-webrtc
2016/10/14 08:00:39
System includes go before own project's includes (
ivoc
2016/10/17 16:05:07
Done.
| |
15 | |
16 namespace { | |
17 | |
18 float power(const float* farend, size_t nr_samples) { | |
hlundin-webrtc
2016/10/14 08:00:39
Power with capital P.
hlundin-webrtc
2016/10/14 08:00:39
With my suggestion in the previous CL to use Array
peah-webrtc
2016/10/14 08:18:57
It is not superimportant, but if you instead use t
peah-webrtc
2016/10/14 08:18:58
Capital P in the function name.
peah-webrtc
2016/10/14 08:18:58
Since you are using this for both farend and neare
kwiberg-webrtc
2016/10/14 08:58:54
The docs suggest that, unless you ask it nicely fo
hlundin-webrtc
2016/10/14 09:15:28
But the current implementation does float * float
peah-webrtc
2016/10/14 13:39:40
In this case, nr_samples is limited to 160. I real
kwiberg-webrtc
2016/10/14 20:33:33
I was going to say that the current implementation
kwiberg-webrtc
2016/10/14 20:33:33
OK, doing it all in float would simplify things. :
hlundin-webrtc
2016/10/14 21:15:46
It seems to me that storing the intermediate as fl
ivoc
2016/10/17 16:05:07
Thanks for all the comments, this seems to be a po
hlundin-webrtc
2016/10/17 18:49:39
Good call!
| |
19 double result = 0.; | |
peah-webrtc
2016/10/14 08:18:58
I think you can use float for the power computatio
ivoc
2016/10/17 16:05:07
Done.
| |
20 for (size_t i = 0; i < nr_samples; i++) { | |
peah-webrtc
2016/10/14 08:18:58
++i is faster
hlundin-webrtc
2016/10/14 21:15:46
Not for a simple scalar. https://google.github.io/
| |
21 result += farend[i] * farend[i]; | |
22 } | |
23 return static_cast<float>(result); | |
peah-webrtc
2016/10/14 08:18:58
If you use float, you don't need the cast.
| |
24 } | |
25 | |
26 } // namespace | |
27 | |
13 namespace webrtc { | 28 namespace webrtc { |
14 | 29 |
15 void EchoDetector::BufferFarend(const float* /*farend*/, | 30 void MeanVarianceEstimator::UpdateEstimate(float value) { |
16 size_t /*num_samples*/) { | 31 mean_ = (1.f - alpha_) * mean_ + alpha_ * value; |
17 // TODO(ivoc): Add implementation. | 32 variance_ = |
33 (1.f - alpha_) * variance_ + alpha_ * (value - mean_) * (value - mean_); | |
18 } | 34 } |
19 | 35 |
20 void EchoDetector::Process(const float* /*nearend*/, size_t /*num_samples*/) { | 36 float MeanVarianceEstimator::SigmaEstimate() { |
21 // TODO(ivoc): Add implementation. | 37 // Variance is >= 0, so this is okay. |
hlundin-webrtc
2016/10/14 08:00:39
DCHECK this assumption.
ivoc
2016/10/17 16:05:08
Done.
| |
38 return sqrtf(variance_); | |
22 } | 39 } |
23 | 40 |
24 void EchoDetector::Initialize(int /*sample_rate_hz*/) { | 41 float MeanVarianceEstimator::MeanEstimate() { |
25 // TODO(ivoc): Add implementation. | 42 return mean_; |
43 } | |
44 | |
45 void MeanVarianceEstimator::Clear() { | |
46 mean_ = 0.f; | |
47 variance_ = 0.f; | |
48 } | |
49 | |
50 void CovarianceEstimator::UpdateCovarianceEstimate(float x, | |
peah-webrtc
2016/10/14 08:18:58
I don't think that covariance is fully correct her
ivoc
2016/10/17 16:05:07
Done.
| |
51 float x_mean, | |
52 float x_sigma, | |
53 float y, | |
54 float y_mean, | |
55 float y_sigma) { | |
56 covariance_ = | |
57 (1.f - alpha_) * covariance_ + alpha_ * (x - x_mean) * (y - y_mean); | |
peah-webrtc
2016/10/14 08:18:58
The style guide mentions that abbreviations should
ivoc
2016/10/17 16:05:07
I chose normalized_cross_correlation.
| |
58 PCC_ = covariance_ / (x_sigma * y_sigma + .0001f); | |
59 } | |
60 | |
61 float CovarianceEstimator::PCCEstimate() { | |
peah-webrtc
2016/10/14 08:18:58
Please change this method name to avoid the abbrev
ivoc
2016/10/17 16:05:07
Done.
| |
62 return PCC_; | |
63 } | |
64 | |
65 void CovarianceEstimator::Clear() { | |
66 covariance_ = 0.f; | |
67 PCC_ = 0.f; | |
68 } | |
69 | |
70 CircularBuffer::CircularBuffer(int size) : buffer_(size), size_(size) {} | |
71 CircularBuffer::~CircularBuffer() {} | |
hlundin-webrtc
2016/10/14 08:00:39
Replace {} with "= default".
peah-webrtc
2016/10/14 08:18:57
Alternatively you can use = default;
ivoc
2016/10/17 16:05:07
Done.
| |
72 | |
73 void CircularBuffer::Insert(float value) { | |
74 buffer_[next_insertion_index_] = value; | |
peah-webrtc
2016/10/14 08:18:57
Please add a DCHECK that next_insertion_index_ < b
ivoc
2016/10/17 16:05:07
Done.
| |
75 next_insertion_index_++; | |
peah-webrtc
2016/10/14 08:18:57
++next_insertion_index_ is faster.
ivoc
2016/10/17 16:05:07
For scalars I don't think it is, but you're right
| |
76 next_insertion_index_ %= size_; | |
peah-webrtc
2016/10/14 08:18:58
buffer_.size() here and elsewhere.
ivoc
2016/10/17 16:05:07
Done.
| |
77 } | |
78 | |
79 float CircularBuffer::GetValue(int delay) { | |
80 RTC_DCHECK(delay >= 0 && delay < size_); | |
hlundin-webrtc
2016/10/14 08:00:39
Separate into two DCHECKs to get better printouts.
ivoc
2016/10/17 16:05:07
Since I changed delay to size_t, the >=0 check doe
| |
81 const int index = (size_ + next_insertion_index_ - delay - 1) % size_; | |
hlundin-webrtc
2016/10/14 08:00:39
size_t
ivoc
2016/10/17 16:05:07
Done.
| |
82 return buffer_[index]; | |
peah-webrtc
2016/10/14 08:18:58
Please add a DCHECK that index < buffer_.size() an
ivoc
2016/10/17 16:05:07
Done.
| |
83 } | |
84 | |
85 void CircularBuffer::Clear() { | |
86 std::fill(buffer_.begin(), buffer_.end(), 0.f); | |
87 next_insertion_index_ = 0; | |
88 } | |
89 | |
90 EchoDetector::EchoDetector() | |
91 : render_buffer_(render_buffer_size_), | |
peah-webrtc
2016/10/14 08:18:58
Do you need to have these in the initializer list?
ivoc
2016/10/17 16:05:07
Good idea!
| |
92 render_power_(lookback_periods_), | |
93 render_power_mean_(lookback_periods_), | |
94 render_power_sigma_(lookback_periods_) {} | |
95 | |
96 EchoDetector::~EchoDetector() {} | |
hlundin-webrtc
2016/10/14 08:00:39
= default
peah-webrtc
2016/10/14 08:18:58
Alternatively you can use = default;
ivoc
2016/10/17 16:05:07
Done.
| |
97 | |
98 void EchoDetector::BufferFarend(const float* farend, size_t num_samples) { | |
peah-webrtc
2016/10/14 08:18:57
After some discussions I think we will be changing
ivoc
2016/10/17 16:05:07
Done.
| |
99 float pow = power(farend, num_samples); | |
peah-webrtc
2016/10/14 08:18:57
If you change the name of the power method to Powe
ivoc
2016/10/17 16:05:07
Done.
| |
100 render_buffer_.Insert(pow); | |
101 render_buffer_delay_ = | |
102 std::min(render_buffer_delay_ + 1, render_buffer_size_ - 1); | |
peah-webrtc
2016/10/14 08:18:57
Why is this minimum needed?
| |
103 } | |
104 | |
105 void EchoDetector::Process(const float* nearend, size_t num_samples) { | |
106 const float cap_pow = power(nearend, num_samples); | |
hlundin-webrtc
2016/10/14 08:00:39
cap_* sounds like a value capped by something.
peah-webrtc
2016/10/14 08:18:57
I think that along the style guide abbreviation ru
ivoc
2016/10/17 16:05:08
Done.
| |
107 capture_variance_.UpdateEstimate(cap_pow); | |
108 const float cap_mean = capture_variance_.MeanEstimate(); | |
109 const float cap_sigma = capture_variance_.SigmaEstimate(); | |
110 float echo_likelihood = 0.f; | |
111 | |
112 const float latest_ren_pow = render_buffer_.GetValue(render_buffer_delay_); | |
peah-webrtc
2016/10/14 08:18:58
This delay is only used to access the most recentl
ivoc
2016/10/17 16:05:07
As discussed offline, I moved the buffer size into
| |
113 render_buffer_delay_ = std::max(0, render_buffer_delay_ - 1); | |
114 render_variance_.UpdateEstimate(latest_ren_pow); | |
115 render_power_.Insert(latest_ren_pow); | |
116 render_power_mean_.Insert(render_variance_.MeanEstimate()); | |
117 render_power_sigma_.Insert(render_variance_.SigmaEstimate()); | |
118 | |
119 for (int delay = 0; delay < lookback_periods_; delay++) { | |
hlundin-webrtc
2016/10/14 08:00:39
size_t
peah-webrtc
2016/10/14 08:18:57
size_t ?
peah-webrtc
2016/10/14 08:18:57
size_t
peah-webrtc
2016/10/14 08:18:58
++delay
peah-webrtc
2016/10/14 08:18:58
This name is not fully clear to me. What is meant
peah-webrtc
2016/10/14 08:18:58
Use covariance_.size()
ivoc
2016/10/17 16:05:07
Done.
| |
120 const float ren_pow = render_power_.GetValue(delay); | |
121 const float ren_mean = render_power_mean_.GetValue(delay); | |
122 const float ren_sigma = render_power_sigma_.GetValue(delay); | |
123 covariance_[delay].UpdateCovarianceEstimate(cap_pow, cap_mean, cap_sigma, | |
124 ren_pow, ren_mean, ren_sigma); | |
125 echo_likelihood = | |
hlundin-webrtc
2016/10/14 08:00:39
No need for the local variable echo_likelihood. Yo
ivoc
2016/10/17 16:05:08
Done.
| |
126 std::max(echo_likelihood, covariance_[delay].PCCEstimate()); | |
127 } | |
128 echo_likelihood_ = echo_likelihood; | |
129 } | |
130 | |
131 void EchoDetector::Initialize(int sample_rate_hz) { | |
hlundin-webrtc
2016/10/14 08:00:39
sample_rate_hz not used? Delete it.
ivoc
2016/10/17 16:05:08
Done.
| |
132 render_buffer_.Clear(); | |
133 render_power_.Clear(); | |
134 render_power_mean_.Clear(); | |
135 render_power_sigma_.Clear(); | |
136 render_variance_.Clear(); | |
137 capture_variance_.Clear(); | |
138 for (auto& cov : covariance_) { | |
139 cov.Clear(); | |
140 } | |
141 echo_likelihood_ = 0.f; | |
142 } | |
143 | |
144 float EchoDetector::EchoLikelihood() { | |
peah-webrtc
2016/10/14 08:18:57
const
ivoc
2016/10/17 16:05:08
Done.
| |
145 return echo_likelihood_; | |
26 } | 146 } |
27 | 147 |
28 } // namespace webrtc | 148 } // namespace webrtc |
OLD | NEW |