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/modules/audio_processing/residual_echo_detector.h" | 11 #include "webrtc/modules/audio_processing/residual_echo_detector.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <numeric> | 14 #include <numeric> |
15 | 15 |
16 #include "webrtc/base/atomicops.h" | 16 #include "webrtc/base/atomicops.h" |
17 #include "webrtc/base/logging.h" | |
17 #include "webrtc/modules/audio_processing/audio_buffer.h" | 18 #include "webrtc/modules/audio_processing/audio_buffer.h" |
18 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" | 19 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" |
19 #include "webrtc/system_wrappers/include/metrics.h" | 20 #include "webrtc/system_wrappers/include/metrics.h" |
20 | 21 |
21 namespace { | 22 namespace { |
22 | 23 |
23 float Power(rtc::ArrayView<const float> input) { | 24 float Power(rtc::ArrayView<const float> input) { |
24 if (input.size() == 0) { | 25 if (input.size() == 0) { |
25 return 0.f; | 26 return 0.f; |
26 } | 27 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 | 107 |
107 // Get the next capture value, update capture statistics and add the relevant | 108 // Get the next capture value, update capture statistics and add the relevant |
108 // values to the buffers. | 109 // values to the buffers. |
109 const float capture_power = Power(capture_audio); | 110 const float capture_power = Power(capture_audio); |
110 capture_statistics_.Update(capture_power); | 111 capture_statistics_.Update(capture_power); |
111 const float capture_mean = capture_statistics_.mean(); | 112 const float capture_mean = capture_statistics_.mean(); |
112 const float capture_std_deviation = capture_statistics_.std_deviation(); | 113 const float capture_std_deviation = capture_statistics_.std_deviation(); |
113 | 114 |
114 // Update the covariance values and determine the new echo likelihood. | 115 // Update the covariance values and determine the new echo likelihood. |
115 echo_likelihood_ = 0.f; | 116 echo_likelihood_ = 0.f; |
117 | |
118 int best_delay = -1; | |
116 for (size_t delay = 0; delay < covariances_.size(); ++delay) { | 119 for (size_t delay = 0; delay < covariances_.size(); ++delay) { |
117 const size_t read_index = | 120 const size_t read_index = |
118 (kLookbackFrames + next_insertion_index_ - delay) % kLookbackFrames; | 121 (kLookbackFrames + next_insertion_index_ - delay) % kLookbackFrames; |
119 RTC_DCHECK_LT(read_index, render_power_.size()); | 122 RTC_DCHECK_LT(read_index, render_power_.size()); |
120 covariances_[delay].Update(capture_power, capture_mean, | 123 covariances_[delay].Update(capture_power, capture_mean, |
121 capture_std_deviation, render_power_[read_index], | 124 capture_std_deviation, render_power_[read_index], |
122 render_power_mean_[read_index], | 125 render_power_mean_[read_index], |
123 render_power_std_dev_[read_index]); | 126 render_power_std_dev_[read_index]); |
124 echo_likelihood_ = std::max( | 127 if (covariances_[delay].normalized_cross_correlation() > echo_likelihood_) { |
125 echo_likelihood_, covariances_[delay].normalized_cross_correlation()); | 128 echo_likelihood_ = covariances_[delay].normalized_cross_correlation(); |
129 best_delay = delay; | |
peah-webrtc
2017/05/17 04:26:15
I guess that the assignment in line 129 may fail o
ivoc
2017/05/17 09:28:07
I don't think it's possible for this assignment to
peah-webrtc
2017/05/17 09:38:07
Sorry, I meant that the compiler will complain. As
ivoc
2017/05/17 11:28:08
Ah, that's a good point. Added static_cast.
| |
130 } | |
126 } | 131 } |
132 // This is a temporary log message to help find the underlying cause for echo | |
133 // likelihoods > 1.0. | |
134 // TODO(ivoc): Remove once the issue is resolved. | |
135 if (echo_likelihood_ > 1.1f) { | |
peah-webrtc
2017/05/17 04:26:15
Not fully sure about the static variable. I'd rath
ivoc
2017/05/17 09:28:07
The reason I chose a static variable is so that al
| |
136 static int log_counter = 0; | |
137 // Make sure we don't spam the log. | |
138 if (log_counter < 5 && best_delay != -1) { | |
139 const size_t read_index = | |
140 (kLookbackFrames + next_insertion_index_ - best_delay) % | |
peah-webrtc
2017/05/17 04:26:15
I just want to point out that the % operator invol
ivoc
2017/05/17 09:28:07
You're right that divisions are slow, but this pie
| |
141 kLookbackFrames; | |
142 RTC_DCHECK_LT(read_index, render_power_.size()); | |
143 LOG_F(LS_ERROR) << "Unexpected high echo likelihood value: " | |
peah-webrtc
2017/05/17 04:26:15
Please consider using j-son type formatting, as in
ivoc
2017/05/17 09:28:07
That seems like a good idea, done.
| |
144 << echo_likelihood_ << ", delay: " << best_delay | |
145 << ", covariance: " | |
146 << covariances_[best_delay].covariance() | |
147 << ", last capture power: " << capture_power | |
148 << ", capture mean: " << capture_mean | |
149 << ", capture_std_deviation: " << capture_std_deviation | |
150 << ", last render power: " << render_power_[read_index] | |
151 << ", render mean: " << render_power_mean_[read_index] | |
152 << ", render std_deviation: " | |
153 << render_power_std_dev_[read_index] | |
154 << ", reliability: " << reliability_; | |
155 log_counter++; | |
156 } | |
157 } | |
158 | |
127 reliability_ = (1.0f - kAlpha) * reliability_ + kAlpha * 1.0f; | 159 reliability_ = (1.0f - kAlpha) * reliability_ + kAlpha * 1.0f; |
128 echo_likelihood_ *= reliability_; | 160 echo_likelihood_ *= reliability_; |
129 // This is a temporary fix to prevent echo likelihood values > 1.0. | 161 // This is a temporary fix to prevent echo likelihood values > 1.0. |
130 // TODO(ivoc): Find the root cause of this issue and fix it. | 162 // TODO(ivoc): Find the root cause of this issue and fix it. |
131 echo_likelihood_ = std::min(echo_likelihood_, 1.0f); | 163 echo_likelihood_ = std::min(echo_likelihood_, 1.0f); |
132 int echo_percentage = static_cast<int>(echo_likelihood_ * 100); | 164 int echo_percentage = static_cast<int>(echo_likelihood_ * 100); |
133 RTC_HISTOGRAM_COUNTS("WebRTC.Audio.ResidualEchoDetector.EchoLikelihood", | 165 RTC_HISTOGRAM_COUNTS("WebRTC.Audio.ResidualEchoDetector.EchoLikelihood", |
134 echo_percentage, 0, 100, 100 /* number of bins */); | 166 echo_percentage, 0, 100, 100 /* number of bins */); |
135 | 167 |
136 // Update the buffer of recent likelihood values. | 168 // Update the buffer of recent likelihood values. |
(...skipping 22 matching lines...) Expand all Loading... | |
159 | 191 |
160 void ResidualEchoDetector::PackRenderAudioBuffer( | 192 void ResidualEchoDetector::PackRenderAudioBuffer( |
161 AudioBuffer* audio, | 193 AudioBuffer* audio, |
162 std::vector<float>* packed_buffer) { | 194 std::vector<float>* packed_buffer) { |
163 packed_buffer->clear(); | 195 packed_buffer->clear(); |
164 packed_buffer->insert(packed_buffer->end(), audio->channels_f()[0], | 196 packed_buffer->insert(packed_buffer->end(), audio->channels_f()[0], |
165 audio->channels_f()[0] + audio->num_frames()); | 197 audio->channels_f()[0] + audio->num_frames()); |
166 } | 198 } |
167 | 199 |
168 } // namespace webrtc | 200 } // namespace webrtc |
OLD | NEW |