1/* 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#define _USE_MATH_DEFINES 12 13#include "webrtc/modules/audio_processing/beamformer/covariance_matrix_generator.h" 14 15#include <cmath> 16 17#include "testing/gtest/include/gtest/gtest.h" 18#include "webrtc/modules/audio_processing/beamformer/matrix_test_helpers.h" 19 20namespace webrtc { 21 22using std::complex; 23 24TEST(CovarianceMatrixGeneratorTest, TestUniformCovarianceMatrix2Mics) { 25 const float kWaveNumber = 0.5775f; 26 const int kNumberMics = 2; 27 const float kMicSpacing = 0.05f; 28 const float kTolerance = 0.0001f; 29 std::vector<Point> geometry; 30 float first_mic = (kNumberMics - 1) * kMicSpacing / 2.f; 31 for (int i = 0; i < kNumberMics; ++i) { 32 geometry.push_back(Point(i * kMicSpacing - first_mic, 0.f, 0.f)); 33 } 34 ComplexMatrix<float> actual_covariance_matrix(kNumberMics, kNumberMics); 35 CovarianceMatrixGenerator::UniformCovarianceMatrix(kWaveNumber, 36 geometry, 37 &actual_covariance_matrix); 38 39 complex<float>* const* actual_els = actual_covariance_matrix.elements(); 40 41 EXPECT_NEAR(actual_els[0][0].real(), 1.f, kTolerance); 42 EXPECT_NEAR(actual_els[0][1].real(), 0.9998f, kTolerance); 43 EXPECT_NEAR(actual_els[1][0].real(), 0.9998f, kTolerance); 44 EXPECT_NEAR(actual_els[1][1].real(), 1.f, kTolerance); 45 46 EXPECT_NEAR(actual_els[0][0].imag(), 0.f, kTolerance); 47 EXPECT_NEAR(actual_els[0][1].imag(), 0.f, kTolerance); 48 EXPECT_NEAR(actual_els[1][0].imag(), 0.f, kTolerance); 49 EXPECT_NEAR(actual_els[1][1].imag(), 0.f, kTolerance); 50} 51 52TEST(CovarianceMatrixGeneratorTest, TestUniformCovarianceMatrix3Mics) { 53 const float kWaveNumber = 10.3861f; 54 const int kNumberMics = 3; 55 const float kMicSpacing = 0.04f; 56 const float kTolerance = 0.0001f; 57 std::vector<Point> geometry; 58 float first_mic = (kNumberMics - 1) * kMicSpacing / 2.f; 59 for (int i = 0; i < kNumberMics; ++i) { 60 geometry.push_back(Point(i * kMicSpacing - first_mic, 0.f, 0.f)); 61 } 62 ComplexMatrix<float> actual_covariance_matrix(kNumberMics, kNumberMics); 63 CovarianceMatrixGenerator::UniformCovarianceMatrix(kWaveNumber, 64 geometry, 65 &actual_covariance_matrix); 66 67 complex<float>* const* actual_els = actual_covariance_matrix.elements(); 68 69 EXPECT_NEAR(actual_els[0][0].real(), 1.f, kTolerance); 70 EXPECT_NEAR(actual_els[0][1].real(), 0.9573f, kTolerance); 71 EXPECT_NEAR(actual_els[0][2].real(), 0.8347f, kTolerance); 72 EXPECT_NEAR(actual_els[1][0].real(), 0.9573f, kTolerance); 73 EXPECT_NEAR(actual_els[1][1].real(), 1.f, kTolerance); 74 EXPECT_NEAR(actual_els[1][2].real(), 0.9573f, kTolerance); 75 EXPECT_NEAR(actual_els[2][0].real(), 0.8347f, kTolerance); 76 EXPECT_NEAR(actual_els[2][1].real(), 0.9573f, kTolerance); 77 EXPECT_NEAR(actual_els[2][2].real(), 1.f, kTolerance); 78 79 EXPECT_NEAR(actual_els[0][0].imag(), 0.f, kTolerance); 80 EXPECT_NEAR(actual_els[0][1].imag(), 0.f, kTolerance); 81 EXPECT_NEAR(actual_els[0][2].imag(), 0.f, kTolerance); 82 EXPECT_NEAR(actual_els[1][0].imag(), 0.f, kTolerance); 83 EXPECT_NEAR(actual_els[1][1].imag(), 0.f, kTolerance); 84 EXPECT_NEAR(actual_els[1][2].imag(), 0.f, kTolerance); 85 EXPECT_NEAR(actual_els[2][0].imag(), 0.f, kTolerance); 86 EXPECT_NEAR(actual_els[2][1].imag(), 0.f, kTolerance); 87 EXPECT_NEAR(actual_els[2][2].imag(), 0.f, kTolerance); 88} 89 90TEST(CovarianceMatrixGeneratorTest, TestUniformCovarianceMatrix3DArray) { 91 const float kWaveNumber = 1.2345f; 92 const int kNumberMics = 4; 93 const float kTolerance = 0.0001f; 94 std::vector<Point> geometry; 95 geometry.push_back(Point(-0.025f, -0.05f, -0.075f)); 96 geometry.push_back(Point(0.075f, -0.05f, -0.075f)); 97 geometry.push_back(Point(-0.025f, 0.15f, -0.075f)); 98 geometry.push_back(Point(-0.025f, -0.05f, 0.225f)); 99 ComplexMatrix<float> actual_covariance_matrix(kNumberMics, kNumberMics); 100 CovarianceMatrixGenerator::UniformCovarianceMatrix(kWaveNumber, 101 geometry, 102 &actual_covariance_matrix); 103 104 complex<float>* const* actual_els = actual_covariance_matrix.elements(); 105 106 EXPECT_NEAR(actual_els[0][0].real(), 1.f, kTolerance); 107 EXPECT_NEAR(actual_els[0][1].real(), 0.9962f, kTolerance); 108 EXPECT_NEAR(actual_els[0][2].real(), 0.9848f, kTolerance); 109 EXPECT_NEAR(actual_els[0][3].real(), 0.9660f, kTolerance); 110 EXPECT_NEAR(actual_els[1][0].real(), 0.9962f, kTolerance); 111 EXPECT_NEAR(actual_els[1][1].real(), 1.f, kTolerance); 112 EXPECT_NEAR(actual_els[1][2].real(), 0.9810f, kTolerance); 113 EXPECT_NEAR(actual_els[1][3].real(), 0.9623f, kTolerance); 114 EXPECT_NEAR(actual_els[2][0].real(), 0.9848f, kTolerance); 115 EXPECT_NEAR(actual_els[2][1].real(), 0.9810f, kTolerance); 116 EXPECT_NEAR(actual_els[2][2].real(), 1.f, kTolerance); 117 EXPECT_NEAR(actual_els[2][3].real(), 0.9511f, kTolerance); 118 EXPECT_NEAR(actual_els[3][0].real(), 0.9660f, kTolerance); 119 EXPECT_NEAR(actual_els[3][1].real(), 0.9623f, kTolerance); 120 EXPECT_NEAR(actual_els[3][2].real(), 0.9511f, kTolerance); 121 EXPECT_NEAR(actual_els[3][3].real(), 1.f, kTolerance); 122 123 EXPECT_NEAR(actual_els[0][0].imag(), 0.f, kTolerance); 124 EXPECT_NEAR(actual_els[0][1].imag(), 0.f, kTolerance); 125 EXPECT_NEAR(actual_els[0][2].imag(), 0.f, kTolerance); 126 EXPECT_NEAR(actual_els[0][3].imag(), 0.f, kTolerance); 127 EXPECT_NEAR(actual_els[1][0].imag(), 0.f, kTolerance); 128 EXPECT_NEAR(actual_els[1][1].imag(), 0.f, kTolerance); 129 EXPECT_NEAR(actual_els[1][2].imag(), 0.f, kTolerance); 130 EXPECT_NEAR(actual_els[1][3].imag(), 0.f, kTolerance); 131 EXPECT_NEAR(actual_els[2][0].imag(), 0.f, kTolerance); 132 EXPECT_NEAR(actual_els[2][1].imag(), 0.f, kTolerance); 133 EXPECT_NEAR(actual_els[2][2].imag(), 0.f, kTolerance); 134 EXPECT_NEAR(actual_els[2][3].imag(), 0.f, kTolerance); 135 EXPECT_NEAR(actual_els[3][0].imag(), 0.f, kTolerance); 136 EXPECT_NEAR(actual_els[3][1].imag(), 0.f, kTolerance); 137 EXPECT_NEAR(actual_els[3][2].imag(), 0.f, kTolerance); 138 EXPECT_NEAR(actual_els[3][3].imag(), 0.f, kTolerance); 139} 140 141TEST(CovarianceMatrixGeneratorTest, TestAngledCovarianceMatrix2Mics) { 142 const float kSpeedOfSound = 340; 143 const float kAngle = static_cast<float>(M_PI) / 4.f; 144 const float kFrequencyBin = 6; 145 const float kFftSize = 512; 146 const int kNumberFrequencyBins = 257; 147 const int kSampleRate = 16000; 148 const int kNumberMics = 2; 149 const float kMicSpacing = 0.04f; 150 const float kTolerance = 0.0001f; 151 std::vector<Point> geometry; 152 float first_mic = (kNumberMics - 1) * kMicSpacing / 2.f; 153 for (int i = 0; i < kNumberMics; ++i) { 154 geometry.push_back(Point(i * kMicSpacing - first_mic, 0.f, 0.f)); 155 } 156 ComplexMatrix<float> actual_covariance_matrix(kNumberMics, kNumberMics); 157 CovarianceMatrixGenerator::AngledCovarianceMatrix(kSpeedOfSound, 158 kAngle, 159 kFrequencyBin, 160 kFftSize, 161 kNumberFrequencyBins, 162 kSampleRate, 163 geometry, 164 &actual_covariance_matrix); 165 166 complex<float>* const* actual_els = actual_covariance_matrix.elements(); 167 168 EXPECT_NEAR(actual_els[0][0].real(), 0.5f, kTolerance); 169 EXPECT_NEAR(actual_els[0][1].real(), 0.4976f, kTolerance); 170 EXPECT_NEAR(actual_els[1][0].real(), 0.4976f, kTolerance); 171 EXPECT_NEAR(actual_els[1][1].real(), 0.5f, kTolerance); 172 173 EXPECT_NEAR(actual_els[0][0].imag(), 0.f, kTolerance); 174 EXPECT_NEAR(actual_els[0][1].imag(), 0.0489f, kTolerance); 175 EXPECT_NEAR(actual_els[1][0].imag(), -0.0489f, kTolerance); 176 EXPECT_NEAR(actual_els[1][1].imag(), 0.f, kTolerance); 177} 178 179TEST(CovarianceMatrixGeneratorTest, TestAngledCovarianceMatrix3Mics) { 180 const float kSpeedOfSound = 340; 181 const float kAngle = static_cast<float>(M_PI) / 4.f; 182 const float kFrequencyBin = 9; 183 const float kFftSize = 512; 184 const int kNumberFrequencyBins = 257; 185 const int kSampleRate = 42000; 186 const int kNumberMics = 3; 187 const float kMicSpacing = 0.05f; 188 const float kTolerance = 0.0001f; 189 std::vector<Point> geometry; 190 float first_mic = (kNumberMics - 1) * kMicSpacing / 2.f; 191 for (int i = 0; i < kNumberMics; ++i) { 192 geometry.push_back(Point(i * kMicSpacing - first_mic, 0.f, 0.f)); 193 } 194 ComplexMatrix<float> actual_covariance_matrix(kNumberMics, kNumberMics); 195 CovarianceMatrixGenerator::AngledCovarianceMatrix(kSpeedOfSound, 196 kAngle, 197 kFrequencyBin, 198 kFftSize, 199 kNumberFrequencyBins, 200 kSampleRate, 201 geometry, 202 &actual_covariance_matrix); 203 204 complex<float>* const* actual_els = actual_covariance_matrix.elements(); 205 206 EXPECT_NEAR(actual_els[0][0].real(), 0.3333f, kTolerance); 207 EXPECT_NEAR(actual_els[0][1].real(), 0.2953f, kTolerance); 208 EXPECT_NEAR(actual_els[0][2].real(), 0.1899f, kTolerance); 209 EXPECT_NEAR(actual_els[1][0].real(), 0.2953f, kTolerance); 210 EXPECT_NEAR(actual_els[1][1].real(), 0.3333f, kTolerance); 211 EXPECT_NEAR(actual_els[1][2].real(), 0.2953f, kTolerance); 212 EXPECT_NEAR(actual_els[2][0].real(), 0.1899f, kTolerance); 213 EXPECT_NEAR(actual_els[2][1].real(), 0.2953f, kTolerance); 214 EXPECT_NEAR(actual_els[2][2].real(), 0.3333f, kTolerance); 215 216 EXPECT_NEAR(actual_els[0][0].imag(), 0.f, kTolerance); 217 EXPECT_NEAR(actual_els[0][1].imag(), 0.1546f, kTolerance); 218 EXPECT_NEAR(actual_els[0][2].imag(), 0.274f, kTolerance); 219 EXPECT_NEAR(actual_els[1][0].imag(), -0.1546f, kTolerance); 220 EXPECT_NEAR(actual_els[1][1].imag(), 0.f, kTolerance); 221 EXPECT_NEAR(actual_els[1][2].imag(), 0.1546f, kTolerance); 222 EXPECT_NEAR(actual_els[2][0].imag(), -0.274f, kTolerance); 223 EXPECT_NEAR(actual_els[2][1].imag(), -0.1546f, kTolerance); 224 EXPECT_NEAR(actual_els[2][2].imag(), 0.f, kTolerance); 225} 226 227// PhaseAlignmentMasks is tested by AngledCovarianceMatrix and by 228// InitBeamformerWeights in BeamformerUnittest. 229 230} // namespace webrtc 231