Make the separation between target and interferer scenario depend on microphone spacing in NonlinearBeamformer
Depends on this CL: https://codereview.webrtc.org/1378973003/
Review URL: https://codereview.webrtc.org/1388033002
Cr-Original-Commit-Position: refs/heads/master@{#10330}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 4a66e4a4d8847cef1e61aec6978f64dddece3d96
diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn
index 9a45cec..2d0c602 100644
--- a/modules/audio_processing/BUILD.gn
+++ b/modules/audio_processing/BUILD.gn
@@ -54,6 +54,8 @@
"audio_buffer.h",
"audio_processing_impl.cc",
"audio_processing_impl.h",
+ "beamformer/array_util.cc",
+ "beamformer/array_util.h",
"beamformer/beamformer.h",
"beamformer/complex_matrix.h",
"beamformer/covariance_matrix_generator.cc",
diff --git a/modules/audio_processing/audio_processing.gypi b/modules/audio_processing/audio_processing.gypi
index a6e8f5c..8f1fbdf 100644
--- a/modules/audio_processing/audio_processing.gypi
+++ b/modules/audio_processing/audio_processing.gypi
@@ -64,6 +64,8 @@
'audio_buffer.h',
'audio_processing_impl.cc',
'audio_processing_impl.h',
+ 'beamformer/array_util.cc',
+ 'beamformer/array_util.h',
'beamformer/beamformer.h',
'beamformer/complex_matrix.h',
'beamformer/covariance_matrix_generator.cc',
diff --git a/modules/audio_processing/beamformer/array_util.cc b/modules/audio_processing/beamformer/array_util.cc
new file mode 100644
index 0000000..c1c4066
--- /dev/null
+++ b/modules/audio_processing/beamformer/array_util.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/audio_processing/beamformer/array_util.h"
+
+#include <algorithm>
+#include <limits>
+
+#include "webrtc/base/checks.h"
+
+namespace webrtc {
+
+float GetMinimumSpacing(const std::vector<Point>& array_geometry) {
+ RTC_CHECK_GT(array_geometry.size(), 1u);
+ float mic_spacing = std::numeric_limits<float>::max();
+ for (size_t i = 0; i < (array_geometry.size() - 1); ++i) {
+ for (size_t j = i + 1; j < array_geometry.size(); ++j) {
+ mic_spacing =
+ std::min(mic_spacing, Distance(array_geometry[i], array_geometry[j]));
+ }
+ }
+ return mic_spacing;
+}
+
+} // namespace webrtc
diff --git a/modules/audio_processing/beamformer/array_util.h b/modules/audio_processing/beamformer/array_util.h
index f7598c0..2ac174e 100644
--- a/modules/audio_processing/beamformer/array_util.h
+++ b/modules/audio_processing/beamformer/array_util.h
@@ -12,6 +12,7 @@
#define WEBRTC_MODULES_AUDIO_PROCESSING_BEAMFORMER_ARRAY_UTIL_H_
#include <cmath>
+#include <vector>
namespace webrtc {
@@ -31,6 +32,10 @@
using Point = CartesianPoint<float>;
+// Returns the minimum distance between any two Points in the given
+// |array_geometry|.
+float GetMinimumSpacing(const std::vector<Point>& array_geometry);
+
template<typename T>
float Distance(CartesianPoint<T> a, CartesianPoint<T> b) {
return std::sqrt((a.x() - b.x()) * (a.x() - b.x()) +
diff --git a/modules/audio_processing/beamformer/array_util_unittest.cc b/modules/audio_processing/beamformer/array_util_unittest.cc
new file mode 100644
index 0000000..57f1708
--- /dev/null
+++ b/modules/audio_processing/beamformer/array_util_unittest.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/audio_processing/beamformer/array_util.h"
+
+#include <vector>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace webrtc {
+
+TEST(ArrayUtilTest, GetMinimumSpacing) {
+ std::vector<Point> array_geometry;
+ array_geometry.push_back(Point(0.f, 0.f, 0.f));
+ array_geometry.push_back(Point(0.1f, 0.f, 0.f));
+ EXPECT_FLOAT_EQ(0.1f, GetMinimumSpacing(array_geometry));
+ array_geometry.push_back(Point(0.f, 0.05f, 0.f));
+ EXPECT_FLOAT_EQ(0.05f, GetMinimumSpacing(array_geometry));
+ array_geometry.push_back(Point(0.f, 0.f, 0.02f));
+ EXPECT_FLOAT_EQ(0.02f, GetMinimumSpacing(array_geometry));
+ array_geometry.push_back(Point(-0.003f, -0.004f, 0.02f));
+ EXPECT_FLOAT_EQ(0.005f, GetMinimumSpacing(array_geometry));
+}
+
+} // namespace webrtc
diff --git a/modules/audio_processing/beamformer/nonlinear_beamformer.cc b/modules/audio_processing/beamformer/nonlinear_beamformer.cc
index 40e738c..20e6b55 100644
--- a/modules/audio_processing/beamformer/nonlinear_beamformer.cc
+++ b/modules/audio_processing/beamformer/nonlinear_beamformer.cc
@@ -36,6 +36,14 @@
// TODO(aluebs): Make the target angle dynamically settable.
const float kTargetAngleRadians = static_cast<float>(M_PI) / 2.f;
+// The minimum separation in radians between the target direction and an
+// interferer scenario.
+const float kMinAwayRadians = 0.2f;
+
+// The separation between the target direction and the closest interferer
+// scenario is proportional to this constant.
+const float kAwaySlope = 0.008f;
+
// When calculating the interference covariance matrix, this is the weight for
// the weighted average between the uniform covariance matrix and the angled
// covariance matrix.
@@ -189,8 +197,9 @@
NonlinearBeamformer::NonlinearBeamformer(
const std::vector<Point>& array_geometry)
- : num_input_channels_(array_geometry.size()),
- array_geometry_(GetCenteredArray(array_geometry)) {
+ : num_input_channels_(array_geometry.size()),
+ array_geometry_(GetCenteredArray(array_geometry)),
+ min_mic_spacing_(GetMinimumSpacing(array_geometry)) {
WindowGenerator::KaiserBesselDerived(kKbdAlpha, kFftSize, window_);
}
@@ -253,8 +262,10 @@
}
void NonlinearBeamformer::InitInterfAngles() {
- // TODO(aluebs): Make kAwayRadians dependent on the mic spacing.
- const float kAwayRadians = 0.5;
+ const float kAwayRadians =
+ std::min(static_cast<float>(M_PI),
+ std::max(kMinAwayRadians, kAwaySlope * static_cast<float>(M_PI) /
+ min_mic_spacing_));
interf_angles_radians_.clear();
// TODO(aluebs): When the target angle is settable, make sure the interferer
diff --git a/modules/audio_processing/beamformer/nonlinear_beamformer.h b/modules/audio_processing/beamformer/nonlinear_beamformer.h
index 4ff0b48..d24bbb6 100644
--- a/modules/audio_processing/beamformer/nonlinear_beamformer.h
+++ b/modules/audio_processing/beamformer/nonlinear_beamformer.h
@@ -116,6 +116,9 @@
const std::vector<Point> array_geometry_;
+ // Minimum spacing between microphone pairs.
+ const float min_mic_spacing_;
+
// Calculated based on user-input and constants in the .cc file.
size_t low_mean_start_bin_;
size_t low_mean_end_bin_;
diff --git a/modules/modules.gyp b/modules/modules.gyp
index 31c3dac..71d200c 100644
--- a/modules/modules.gyp
+++ b/modules/modules.gyp
@@ -168,6 +168,7 @@
# 'audio_processing/agc/agc_unittest.cc',
'audio_processing/agc/histogram_unittest.cc',
'audio_processing/agc/mock_agc.h',
+ 'audio_processing/beamformer/array_util_unittest.cc',
'audio_processing/beamformer/complex_matrix_unittest.cc',
'audio_processing/beamformer/covariance_matrix_generator_unittest.cc',
'audio_processing/beamformer/matrix_unittest.cc',