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

Side by Side Diff: webrtc/modules/audio_processing/beamformer/nonlinear_beamformer.cc

Issue 1388033002: Make the separation between target and interferer scenario depend on microphone spacing in Nonlinea… (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@nlbf3
Patch Set: Widen beam Created 5 years, 2 months 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) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 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
(...skipping 18 matching lines...) Expand all
29 29
30 const float kSpeedOfSoundMeterSeconds = 343; 30 const float kSpeedOfSoundMeterSeconds = 343;
31 31
32 // For both target and interference angles, PI / 2 is perpendicular to the 32 // For both target and interference angles, PI / 2 is perpendicular to the
33 // microphone array, facing forwards. The positive direction goes 33 // microphone array, facing forwards. The positive direction goes
34 // counterclockwise. 34 // counterclockwise.
35 // The angle at which we amplify sound. 35 // The angle at which we amplify sound.
36 // TODO(aluebs): Make the target angle dynamically settable. 36 // TODO(aluebs): Make the target angle dynamically settable.
37 const float kTargetAngleRadians = static_cast<float>(M_PI) / 2.f; 37 const float kTargetAngleRadians = static_cast<float>(M_PI) / 2.f;
38 38
39 // The minimum separation in radians between the target direction and a
Andrew MacDonald 2015/10/14 23:38:53 and an interferer
aluebs-webrtc 2015/10/17 00:54:49 Done.
40 // interferer scenario.
41 const float kMinAwayRadians = 0.2f;
42
43 // The separation between the target direction and the closest interferer
44 // scenario is proportional to this constant.
45 const float kAwaySlope = 0.008f;
46
39 // When calculating the interference covariance matrix, this is the weight for 47 // When calculating the interference covariance matrix, this is the weight for
40 // the weighted average between the uniform covariance matrix and the angled 48 // the weighted average between the uniform covariance matrix and the angled
41 // covariance matrix. 49 // covariance matrix.
42 // Rpsi = Rpsi_angled * kBalance + Rpsi_uniform * (1 - kBalance) 50 // Rpsi = Rpsi_angled * kBalance + Rpsi_uniform * (1 - kBalance)
43 const float kBalance = 0.95f; 51 const float kBalance = 0.95f;
44 52
45 const float kHalfBeamWidthRadians = static_cast<float>(M_PI) * 20.f / 180.f; 53 const float kHalfBeamWidthRadians = static_cast<float>(M_PI) * 20.f / 180.f;
46 54
47 // Alpha coefficients for mask smoothing. 55 // Alpha coefficients for mask smoothing.
48 const float kMaskTimeSmoothAlpha = 0.2f; 56 const float kMaskTimeSmoothAlpha = 0.2f;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 center += array_geometry[i].c[dim]; 184 center += array_geometry[i].c[dim];
177 } 185 }
178 center /= array_geometry.size(); 186 center /= array_geometry.size();
179 for (size_t i = 0; i < array_geometry.size(); ++i) { 187 for (size_t i = 0; i < array_geometry.size(); ++i) {
180 array_geometry[i].c[dim] -= center; 188 array_geometry[i].c[dim] -= center;
181 } 189 }
182 } 190 }
183 return array_geometry; 191 return array_geometry;
184 } 192 }
185 193
194 float GetMinimumSpacing(std::vector<Point> array_geometry) {
Andrew MacDonald 2015/10/14 23:38:53 const reference
aluebs-webrtc 2015/10/17 00:54:50 Done.
195 float mic_spacing = Distance(array_geometry[0], array_geometry[1]);
196 for (size_t i = 0; i < (array_geometry.size() - 1); ++i) {
197 for (size_t j = i + 1; j < array_geometry.size(); ++j) {
198 float distance = Distance(array_geometry[i], array_geometry[j]);
Andrew MacDonald 2015/10/14 23:38:53 Not a big deal, but you're computing the first dis
aluebs-webrtc 2015/10/17 00:54:49 Good suggestion. Done.
199 if (distance < mic_spacing) {
200 mic_spacing = distance;
201 }
202 }
203 }
204 return mic_spacing;
205 }
206
186 } // namespace 207 } // namespace
187 208
188 // static 209 // static
189 const size_t NonlinearBeamformer::kNumFreqBins; 210 const size_t NonlinearBeamformer::kNumFreqBins;
190 211
191 NonlinearBeamformer::NonlinearBeamformer( 212 NonlinearBeamformer::NonlinearBeamformer(
192 const std::vector<Point>& array_geometry) 213 const std::vector<Point>& array_geometry)
193 : num_input_channels_(array_geometry.size()), 214 : num_input_channels_(array_geometry.size()),
194 array_geometry_(GetCenteredArray(array_geometry)) { 215 array_geometry_(GetCenteredArray(array_geometry)),
216 mic_spacing_(GetMinimumSpacing(array_geometry)) {
195 WindowGenerator::KaiserBesselDerived(kKbdAlpha, kFftSize, window_); 217 WindowGenerator::KaiserBesselDerived(kKbdAlpha, kFftSize, window_);
196 } 218 }
197 219
198 void NonlinearBeamformer::Initialize(int chunk_size_ms, int sample_rate_hz) { 220 void NonlinearBeamformer::Initialize(int chunk_size_ms, int sample_rate_hz) {
199 chunk_length_ = 221 chunk_length_ =
200 static_cast<size_t>(sample_rate_hz / (1000.f / chunk_size_ms)); 222 static_cast<size_t>(sample_rate_hz / (1000.f / chunk_size_ms));
201 sample_rate_hz_ = sample_rate_hz; 223 sample_rate_hz_ = sample_rate_hz;
202 low_mean_start_bin_ = Round(kLowMeanStartHz * kFftSize / sample_rate_hz_); 224 low_mean_start_bin_ = Round(kLowMeanStartHz * kFftSize / sample_rate_hz_);
203 low_mean_end_bin_ = Round(kLowMeanEndHz * kFftSize / sample_rate_hz_); 225 low_mean_end_bin_ = Round(kLowMeanEndHz * kFftSize / sample_rate_hz_);
204 high_mean_start_bin_ = Round(kHighMeanStartHz * kFftSize / sample_rate_hz_); 226 high_mean_start_bin_ = Round(kHighMeanStartHz * kFftSize / sample_rate_hz_);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 for (size_t i = 0; i < kNumFreqBins; ++i) { 269 for (size_t i = 0; i < kNumFreqBins; ++i) {
248 rxiws_[i] = Norm(target_cov_mats_[i], delay_sum_masks_[i]); 270 rxiws_[i] = Norm(target_cov_mats_[i], delay_sum_masks_[i]);
249 rpsiws_[i].clear(); 271 rpsiws_[i].clear();
250 for (size_t j = 0; j < interf_angles_radians_.size(); ++j) { 272 for (size_t j = 0; j < interf_angles_radians_.size(); ++j) {
251 rpsiws_[i].push_back(Norm(*interf_cov_mats_[i][j], delay_sum_masks_[i])); 273 rpsiws_[i].push_back(Norm(*interf_cov_mats_[i][j], delay_sum_masks_[i]));
252 } 274 }
253 } 275 }
254 } 276 }
255 277
256 void NonlinearBeamformer::InitInterfAngles() { 278 void NonlinearBeamformer::InitInterfAngles() {
257 // TODO(aluebs): Make kAway dependent on the mic spacing. 279 const float kAway =
258 const float kAway = 0.5; 280 std::min(static_cast<float>(M_PI),
281 std::max(kMinAwayRadians,
282 kAwaySlope * static_cast<float>(M_PI) / mic_spacing_));
259 283
260 interf_angles_radians_.clear(); 284 interf_angles_radians_.clear();
261 // TODO(aluebs): When the target angle is settable, make sure the interferer 285 // TODO(aluebs): When the target angle is settable, make sure the interferer
262 // scenarios aren't reflected over the target one for linear geometries. 286 // scenarios aren't reflected over the target one for linear geometries.
263 interf_angles_radians_.push_back(kTargetAngleRadians - kAway); 287 interf_angles_radians_.push_back(kTargetAngleRadians - kAway);
264 interf_angles_radians_.push_back(kTargetAngleRadians + kAway); 288 interf_angles_radians_.push_back(kTargetAngleRadians + kAway);
265 } 289 }
266 290
267 void NonlinearBeamformer::InitDelaySumMasks() { 291 void NonlinearBeamformer::InitDelaySumMasks() {
268 for (size_t f_ix = 0; f_ix < kNumFreqBins; ++f_ix) { 292 for (size_t f_ix = 0; f_ix < kNumFreqBins; ++f_ix) {
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 new_mask_ + high_mean_end_bin_ + 1); 539 new_mask_ + high_mean_end_bin_ + 1);
516 if (new_mask_[quantile] > kMaskTargetThreshold) { 540 if (new_mask_[quantile] > kMaskTargetThreshold) {
517 is_target_present_ = true; 541 is_target_present_ = true;
518 interference_blocks_count_ = 0; 542 interference_blocks_count_ = 0;
519 } else { 543 } else {
520 is_target_present_ = interference_blocks_count_++ < hold_target_blocks_; 544 is_target_present_ = interference_blocks_count_++ < hold_target_blocks_;
521 } 545 }
522 } 546 }
523 547
524 } // namespace webrtc 548 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698