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

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

Issue 1806853004: Added a bitexactness test for the beamformer in the audio processing module (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@AgcBitExactness_CL
Patch Set: Disabled all the bitexactness tests for the beamformer due to problems with division by zero in the… Created 4 years, 8 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 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 // MSVC++ requires this to be set before any other includes to get M_PI. 11 // MSVC++ requires this to be set before any other includes to get M_PI.
12 #define _USE_MATH_DEFINES 12 #define _USE_MATH_DEFINES
13 13
14 #include "webrtc/modules/audio_processing/beamformer/nonlinear_beamformer.h" 14 #include "webrtc/modules/audio_processing/beamformer/nonlinear_beamformer.h"
15 15
16 #include <math.h> 16 #include <math.h>
17 17
18 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "webrtc/base/array_view.h"
20 #include "webrtc/modules/audio_processing/audio_buffer.h"
21 #include "webrtc/modules/audio_processing/test/audio_buffer_tools.h"
22 #include "webrtc/modules/audio_processing/test/bitexactness_tools.h"
19 23
20 namespace webrtc { 24 namespace webrtc {
21 namespace { 25 namespace {
22 26
23 const int kChunkSizeMs = 10; 27 const int kChunkSizeMs = 10;
24 const int kSampleRateHz = 16000; 28 const int kSampleRateHz = 16000;
25 29
26 SphericalPointf AzimuthToSphericalPoint(float azimuth_radians) { 30 SphericalPointf AzimuthToSphericalPoint(float azimuth_radians) {
27 return SphericalPointf(azimuth_radians, 0.f, 1.f); 31 return SphericalPointf(azimuth_radians, 0.f, 1.f);
28 } 32 }
(...skipping 12 matching lines...) Expand all
41 EXPECT_FALSE(bf->IsInBeam(AzimuthToSphericalPoint( 45 EXPECT_FALSE(bf->IsInBeam(AzimuthToSphericalPoint(
42 target_azimuth_radians + NonlinearBeamformer::kHalfBeamWidthRadians + 46 target_azimuth_radians + NonlinearBeamformer::kHalfBeamWidthRadians +
43 0.001f))); 47 0.001f)));
44 } 48 }
45 49
46 void AimAndVerify(NonlinearBeamformer* bf, float target_azimuth_radians) { 50 void AimAndVerify(NonlinearBeamformer* bf, float target_azimuth_radians) {
47 bf->AimAt(AzimuthToSphericalPoint(target_azimuth_radians)); 51 bf->AimAt(AzimuthToSphericalPoint(target_azimuth_radians));
48 Verify(bf, target_azimuth_radians); 52 Verify(bf, target_azimuth_radians);
49 } 53 }
50 54
55 // Bitexactness test code.
56 const size_t kNumFramesToProcess = 1000;
57
58 void ProcessOneFrame(int sample_rate_hz,
59 AudioBuffer* capture_audio_buffer,
60 Beamformer<float>* beamformer) {
61 if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) {
62 capture_audio_buffer->SplitIntoFrequencyBands();
63 }
64
65 beamformer->ProcessChunk(*capture_audio_buffer->split_data_f(),
66 capture_audio_buffer->split_data_f());
67 capture_audio_buffer->set_num_channels(1);
68
69 if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) {
70 capture_audio_buffer->MergeFrequencyBands();
71 }
72 }
73
74 int BeamformerSampleRate(int sample_rate_hz) {
75 return (sample_rate_hz > AudioProcessing::kSampleRate16kHz
76 ? AudioProcessing::kSampleRate16kHz
77 : sample_rate_hz);
78 }
79
80 void RunBitExactnessTest(int sample_rate_hz,
81 const std::vector<Point>& array_geometry,
82 const SphericalPointf& target_direction,
83 rtc::ArrayView<const float> output_reference) {
84 NonlinearBeamformer beamformer(array_geometry, target_direction);
85 beamformer.Initialize(AudioProcessing::kChunkSizeMs,
86 BeamformerSampleRate(sample_rate_hz));
87
88 const StreamConfig capture_config(sample_rate_hz, array_geometry.size(),
89 false);
90 AudioBuffer capture_buffer(
91 capture_config.num_frames(), capture_config.num_channels(),
92 capture_config.num_frames(), capture_config.num_channels(),
93 capture_config.num_frames());
94 test::InputAudioFile capture_file(
95 test::GetApmCaptureTestVectorFileName(sample_rate_hz));
96 std::vector<float> capture_input(capture_config.num_frames() *
97 capture_config.num_channels());
98 for (size_t frame_no = 0u; frame_no < kNumFramesToProcess; ++frame_no) {
99 ReadFloatSamplesFromStereoFile(capture_config.num_frames(),
100 capture_config.num_channels(), &capture_file,
101 capture_input);
102
103 test::CopyVectorToAudioBuffer(capture_config, capture_input,
104 &capture_buffer);
105
106 ProcessOneFrame(sample_rate_hz, &capture_buffer, &beamformer);
107 }
108
109 // Extract and verify the test results.
110 std::vector<float> capture_output;
111 test::ExtractVectorFromAudioBuffer(capture_config, &capture_buffer,
112 &capture_output);
113
114 const float kTolerance = 1.f / static_cast<float>(1 << 15);
115
116 // Compare the output with the reference. Only the first values of the output
117 // from last frame processed are compared in order not having to specify all
118 // preceeding frames as testvectors. As the algorithm being tested has a
119 // memory, testing only the last frame implicitly also tests the preceeding
120 // frames.
121 EXPECT_TRUE(test::BitExactFrame(
122 capture_config.num_frames(), capture_config.num_channels(),
123 output_reference, capture_output, kTolerance));
124 }
125
126 std::vector<Point> CreateArrayGeometry(int variant) {
127 std::vector<Point> array_geometry;
128 switch (variant) {
129 case 1:
130 array_geometry.push_back(Point(-0.025f, 0.f, 0.f));
131 array_geometry.push_back(Point(0.025f, 0.f, 0.f));
132 break;
133 case 2:
134 array_geometry.push_back(Point(-0.035f, 0.f, 0.f));
135 array_geometry.push_back(Point(0.035f, 0.f, 0.f));
136 break;
137 case 3:
138 array_geometry.push_back(Point(-0.5f, 0.f, 0.f));
139 array_geometry.push_back(Point(0.5f, 0.f, 0.f));
140 break;
141 default:
142 RTC_CHECK(false);
143 }
144 return array_geometry;
145 }
146
147 const SphericalPointf TargetDirection1(0.4f * static_cast<float>(M_PI) / 2.f,
148 0.f,
149 1.f);
150 const SphericalPointf TargetDirection2(static_cast<float>(M_PI) / 2.f,
151 1.f,
152 2.f);
153
51 } // namespace 154 } // namespace
52 155
53 TEST(NonlinearBeamformerTest, AimingModifiesBeam) { 156 TEST(NonlinearBeamformerTest, AimingModifiesBeam) {
54 std::vector<Point> array_geometry; 157 std::vector<Point> array_geometry;
55 array_geometry.push_back(Point(-0.025f, 0.f, 0.f)); 158 array_geometry.push_back(Point(-0.025f, 0.f, 0.f));
56 array_geometry.push_back(Point(0.025f, 0.f, 0.f)); 159 array_geometry.push_back(Point(0.025f, 0.f, 0.f));
57 NonlinearBeamformer bf(array_geometry); 160 NonlinearBeamformer bf(array_geometry);
58 bf.Initialize(kChunkSizeMs, kSampleRateHz); 161 bf.Initialize(kChunkSizeMs, kSampleRateHz);
59 // The default constructor parameter sets the target angle to PI / 2. 162 // The default constructor parameter sets the target angle to PI / 2.
60 Verify(&bf, static_cast<float>(M_PI) / 2.f); 163 Verify(&bf, static_cast<float>(M_PI) / 2.f);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 bf.interf_angles_radians_[0]); 240 bf.interf_angles_radians_[0]);
138 EXPECT_FLOAT_EQ(M_PI / 2.f + bf.away_radians_, 241 EXPECT_FLOAT_EQ(M_PI / 2.f + bf.away_radians_,
139 bf.interf_angles_radians_[1]); 242 bf.interf_angles_radians_[1]);
140 bf.AimAt(AzimuthToSphericalPoint(bf.away_radians_ / 2.f)); 243 bf.AimAt(AzimuthToSphericalPoint(bf.away_radians_ / 2.f));
141 EXPECT_EQ(2u, bf.interf_angles_radians_.size()); 244 EXPECT_EQ(2u, bf.interf_angles_radians_.size());
142 EXPECT_FLOAT_EQ(-bf.away_radians_ / 2.f, bf.interf_angles_radians_[0]); 245 EXPECT_FLOAT_EQ(-bf.away_radians_ / 2.f, bf.interf_angles_radians_[0]);
143 EXPECT_FLOAT_EQ(3.f * bf.away_radians_ / 2.f, bf.interf_angles_radians_[1]); 246 EXPECT_FLOAT_EQ(3.f * bf.away_radians_ / 2.f, bf.interf_angles_radians_[1]);
144 } 247 }
145 } 248 }
146 249
250 // TODO(peah): Investigate why the nonlinear_beamformer.cc causes a DCHECK in
251 // this setup.
252 TEST(BeamformerBitExactnessTest,
253 DISABLED_Stereo8kHz_ArrayGeometry1_TargetDirection1) {
254 const float kOutputReference[] = {0.001318f, -0.001091f, 0.000990f,
255 0.001318f, -0.001091f, 0.000990f};
256
257 RunBitExactnessTest(AudioProcessing::kSampleRate8kHz, CreateArrayGeometry(1),
258 TargetDirection1, kOutputReference);
259 }
260
261 TEST(BeamformerBitExactnessTest,
262 DISABLED_Stereo16kHz_ArrayGeometry1_TargetDirection1) {
263 const float kOutputReference[] = {0.000064f, 0.000211f, 0.000075f,
264 0.000064f, 0.000211f, 0.000075f};
265
266 RunBitExactnessTest(AudioProcessing::kSampleRate16kHz, CreateArrayGeometry(1),
267 TargetDirection1, kOutputReference);
268 }
269
270 TEST(BeamformerBitExactnessTest,
271 DISABLED_Stereo32kHz_ArrayGeometry1_TargetDirection1) {
272 const float kOutputReference[] = {0.000183f, 0.000183f, 0.000183f,
273 0.000183f, 0.000183f, 0.000183f};
274
275 RunBitExactnessTest(AudioProcessing::kSampleRate32kHz, CreateArrayGeometry(1),
276 TargetDirection1, kOutputReference);
277 }
278
279 TEST(BeamformerBitExactnessTest,
280 DISABLED_Stereo48kHz_ArrayGeometry1_TargetDirection1) {
281 const float kOutputReference[] = {0.000155f, 0.000152f, 0.000159f,
282 0.000155f, 0.000152f, 0.000159f};
283
284 RunBitExactnessTest(AudioProcessing::kSampleRate48kHz, CreateArrayGeometry(1),
285 TargetDirection1, kOutputReference);
286 }
287
288 // TODO(peah): Investigate why the nonlinear_beamformer.cc causes a DCHECK in
289 // this setup.
290 TEST(BeamformerBitExactnessTest,
291 DISABLED_Stereo8kHz_ArrayGeometry1_TargetDirection2) {
292 const float kOutputReference[] = {0.001144f, -0.001026f, 0.001074f,
293 -0.016205f, -0.007324f, -0.015656f};
294
295 RunBitExactnessTest(AudioProcessing::kSampleRate8kHz, CreateArrayGeometry(1),
296 TargetDirection2, kOutputReference);
297 }
298
299 TEST(BeamformerBitExactnessTest,
300 DISABLED_Stereo16kHz_ArrayGeometry1_TargetDirection2) {
301 const float kOutputReference[] = {0.001144f, -0.001026f, 0.001074f,
302 0.001144f, -0.001026f, 0.001074f};
303
304 RunBitExactnessTest(AudioProcessing::kSampleRate16kHz, CreateArrayGeometry(1),
305 TargetDirection2, kOutputReference);
306 }
307
308 TEST(BeamformerBitExactnessTest,
309 DISABLED_Stereo32kHz_ArrayGeometry1_TargetDirection2) {
310 const float kOutputReference[] = {0.000732f, -0.000397f, 0.000610f,
311 0.000732f, -0.000397f, 0.000610f};
312
313 RunBitExactnessTest(AudioProcessing::kSampleRate32kHz, CreateArrayGeometry(1),
314 TargetDirection2, kOutputReference);
315 }
316
317 TEST(BeamformerBitExactnessTest,
318 DISABLED_Stereo48kHz_ArrayGeometry1_TargetDirection2) {
319 const float kOutputReference[] = {0.000106f, -0.000464f, 0.000188f,
320 0.000106f, -0.000464f, 0.000188f};
321
322 RunBitExactnessTest(AudioProcessing::kSampleRate48kHz, CreateArrayGeometry(1),
323 TargetDirection2, kOutputReference);
324 }
325
326 TEST(BeamformerBitExactnessTest,
327 DISABLED_Stereo8kHz_ArrayGeometry2_TargetDirection2) {
328 const float kOutputReference[] = {-0.000649f, 0.000576f, -0.000148f,
329 -0.000649f, 0.000576f, -0.000148f};
330
331 RunBitExactnessTest(AudioProcessing::kSampleRate8kHz, CreateArrayGeometry(2),
332 TargetDirection2, kOutputReference);
333 }
334
335 TEST(BeamformerBitExactnessTest,
336 DISABLED_Stereo16kHz_ArrayGeometry2_TargetDirection2) {
337 const float kOutputReference[] = {0.000808f, -0.000695f, 0.000739f,
338 0.000808f, -0.000695f, 0.000739f};
339
340 RunBitExactnessTest(AudioProcessing::kSampleRate16kHz, CreateArrayGeometry(2),
341 TargetDirection2, kOutputReference);
342 }
343
344 TEST(BeamformerBitExactnessTest,
345 DISABLED_Stereo32kHz_ArrayGeometry2_TargetDirection2) {
346 const float kOutputReference[] = {0.000580f, -0.000183f, 0.000458f,
347 0.000580f, -0.000183f, 0.000458f};
348
349 RunBitExactnessTest(AudioProcessing::kSampleRate32kHz, CreateArrayGeometry(2),
350 TargetDirection2, kOutputReference);
351 }
352
353 TEST(BeamformerBitExactnessTest,
354 DISABLED_Stereo48kHz_ArrayGeometry2_TargetDirection2) {
355 const float kOutputReference[] = {0.000075f, -0.000288f, 0.000156f,
356 0.000075f, -0.000288f, 0.000156f};
357
358 RunBitExactnessTest(AudioProcessing::kSampleRate48kHz, CreateArrayGeometry(2),
359 TargetDirection2, kOutputReference);
360 }
361
362 // TODO(peah): Investigate why the nonlinear_beamformer.cc causes a DCHECK in
363 // this setup.
364 TEST(BeamformerBitExactnessTest,
365 DISABLED_Stereo16kHz_ArrayGeometry3_TargetDirection1) {
366 const float kOutputReference[] = {-0.000161f, 0.000171f, -0.000096f,
367 0.001007f, 0.000427f, 0.000977f};
368
369 RunBitExactnessTest(AudioProcessing::kSampleRate16kHz, CreateArrayGeometry(3),
370 TargetDirection1, kOutputReference);
371 }
372
147 } // namespace webrtc 373 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698