Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright (c) 2016 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 #include <vector> | |
| 11 | |
| 12 #include "testing/gtest/include/gtest/gtest.h" | |
| 13 #include "webrtc/base/array_view.h" | |
| 14 #include "webrtc/modules/audio_processing/audio_buffer.h" | |
| 15 #include "webrtc/modules/audio_processing/beamformer/nonlinear_beamformer.h" | |
| 16 #include "webrtc/modules/audio_processing/test/audio_buffer_tools.h" | |
| 17 #include "webrtc/modules/audio_processing/test/bitexactness_tools.h" | |
| 18 | |
| 19 namespace webrtc { | |
| 20 namespace { | |
| 21 | |
| 22 const size_t kNumFramesToProcess = 1000; | |
| 23 | |
| 24 void ProcessOneFrame(int sample_rate_hz, | |
| 25 AudioBuffer* capture_audio_buffer, | |
| 26 Beamformer<float>* beamformer) { | |
| 27 if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) { | |
| 28 capture_audio_buffer->SplitIntoFrequencyBands(); | |
| 29 } | |
| 30 | |
| 31 beamformer->ProcessChunk(*capture_audio_buffer->split_data_f(), | |
| 32 capture_audio_buffer->split_data_f()); | |
| 33 capture_audio_buffer->set_num_channels(1); | |
| 34 | |
| 35 if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) { | |
| 36 capture_audio_buffer->MergeFrequencyBands(); | |
| 37 } | |
| 38 } | |
| 39 | |
| 40 int BeamformerSampleRate(int sample_rate_hz) { | |
| 41 return (sample_rate_hz > AudioProcessing::kSampleRate16kHz | |
| 42 ? AudioProcessing::kSampleRate16kHz | |
| 43 : sample_rate_hz); | |
| 44 } | |
| 45 | |
| 46 void RunBitExactnessTest(int sample_rate_hz, | |
| 47 const std::vector<Point>& array_geometry, | |
| 48 const SphericalPointf& target_direction, | |
| 49 rtc::ArrayView<const float> output_reference) { | |
| 50 NonlinearBeamformer beamformer(array_geometry, target_direction); | |
| 51 beamformer.Initialize(AudioProcessing::kChunkSizeMs, | |
| 52 BeamformerSampleRate(sample_rate_hz)); | |
| 53 | |
| 54 const StreamConfig capture_config(sample_rate_hz, array_geometry.size(), | |
| 55 false); | |
| 56 AudioBuffer capture_buffer( | |
| 57 capture_config.num_frames(), capture_config.num_channels(), | |
| 58 capture_config.num_frames(), capture_config.num_channels(), | |
| 59 capture_config.num_frames()); | |
| 60 test::InputAudioFile capture_file( | |
| 61 test::GetApmCaptureTestVectorFileName(sample_rate_hz)); | |
| 62 std::vector<float> capture_input(capture_config.num_frames() * | |
| 63 capture_config.num_channels()); | |
| 64 for (size_t frame_no = 0u; frame_no < kNumFramesToProcess; ++frame_no) { | |
| 65 ReadFloatSamplesFromStereoFile(capture_config.num_frames(), | |
| 66 capture_config.num_channels(), &capture_file, | |
| 67 capture_input); | |
| 68 | |
| 69 test::CopyVectorToAudioBuffer(capture_config, capture_input, | |
| 70 &capture_buffer); | |
| 71 | |
| 72 ProcessOneFrame(sample_rate_hz, &capture_buffer, &beamformer); | |
| 73 } | |
| 74 | |
| 75 // Extract and verify the test results. | |
| 76 std::vector<float> capture_output; | |
| 77 test::ExtractVectorFromAudioBuffer(capture_config, &capture_buffer, | |
| 78 &capture_output); | |
| 79 | |
| 80 const float kTolerance = 1.f / static_cast<float>(1 << 15); | |
| 81 | |
| 82 // Compare the output with the reference. Only the first values of the output | |
| 83 // from last frame processed are compared in order not having to specify all | |
| 84 // preceeding frames as testvectors. As the algorithm being tested has a | |
| 85 // memory, testing only the last frame implicitly also tests the preceeding | |
| 86 // frames. | |
| 87 EXPECT_TRUE(test::BitExactFrame( | |
| 88 capture_config.num_frames(), capture_config.num_channels(), | |
| 89 output_reference, capture_output, kTolerance)); | |
| 90 } | |
| 91 | |
| 92 std::vector<Point> CreateArrayGeometry(int variant) { | |
| 93 std::vector<Point> array_geometry; | |
| 94 switch (variant) { | |
| 95 case 1: | |
| 96 array_geometry.push_back(Point(-0.025f, 0.f, 0.f)); | |
| 97 array_geometry.push_back(Point(0.025f, 0.f, 0.f)); | |
| 98 break; | |
| 99 case 2: | |
| 100 array_geometry.push_back(Point(-0.035f, 0.f, 0.f)); | |
| 101 array_geometry.push_back(Point(0.035f, 0.f, 0.f)); | |
| 102 break; | |
| 103 case 3: | |
| 104 array_geometry.push_back(Point(-0.5f, 0.f, 0.f)); | |
| 105 array_geometry.push_back(Point(0.5f, 0.f, 0.f)); | |
| 106 break; | |
| 107 case 4: | |
|
aluebs-webrtc
2016/03/22 12:15:56
The 4th case is never called.
peah-webrtc
2016/03/23 22:06:20
Good catch, missed actually using that configurati
aluebs-webrtc
2016/03/24 11:14:25
Acknowledged.
| |
| 108 array_geometry.push_back(Point(-0.5f, 0.f, 0.f)); | |
| 109 array_geometry.push_back(Point(0.1f, 0.f, 0.f)); | |
| 110 array_geometry.push_back(Point(0.5f, 0.f, 0.f)); | |
| 111 break; | |
| 112 default: | |
| 113 RTC_CHECK(false); | |
| 114 } | |
| 115 return array_geometry; | |
| 116 } | |
| 117 | |
| 118 const SphericalPointf TargetDirection1(static_cast<float>(M_PI) / 2.f, | |
| 119 0.f, | |
| 120 1.f); | |
| 121 const SphericalPointf TargetDirection2(static_cast<float>(M_PI) / 2.f, | |
| 122 1.f, | |
| 123 2.f); | |
| 124 | |
| 125 } // namespace | |
| 126 | |
| 127 // TODO(peah): Investigate why the nonlinear_beamformer.cc causes a DCHECK in | |
| 128 // this setup. | |
| 129 TEST(BeamformerBitExactnessTest, | |
| 130 DISABLED_Stereo8kHz_ArrayGeometry1_TargetDirection1) { | |
| 131 const float kOutputReference[] = {-0.000161f, 0.000171f, -0.000096f, | |
| 132 0.001007f, 0.000427f, 0.000977f}; | |
| 133 | |
| 134 RunBitExactnessTest(AudioProcessing::kSampleRate8kHz, CreateArrayGeometry(1), | |
| 135 TargetDirection1, kOutputReference); | |
| 136 } | |
| 137 | |
| 138 TEST(BeamformerBitExactnessTest, Stereo16kHz_ArrayGeometry1_TargetDirection1) { | |
| 139 const float kOutputReference[] = {0.001144f, -0.001026f, 0.001074f, | |
| 140 0.001144f, -0.001026f, 0.001074f}; | |
|
aluebs-webrtc
2016/03/22 12:15:56
Why did these change?
peah-webrtc
2016/03/23 22:06:20
I'm not sure. It may be that the beamformer testve
aluebs-webrtc
2016/03/24 11:14:25
This exactly the reason I think these kind of test
peah-webrtc
2016/03/24 11:51:30
The bitexactness tests are there to identify when
aluebs-webrtc
2016/03/28 23:01:17
I am still not convinced, but let's discuss offlin
| |
| 141 | |
| 142 RunBitExactnessTest(AudioProcessing::kSampleRate16kHz, CreateArrayGeometry(1), | |
| 143 TargetDirection1, kOutputReference); | |
| 144 } | |
| 145 | |
| 146 TEST(BeamformerBitExactnessTest, Stereo32kHz_ArrayGeometry1_TargetDirection1) { | |
| 147 const float kOutputReference[] = {0.000732f, -0.000397f, 0.000610f, | |
| 148 0.000732f, -0.000397f, 0.000610f}; | |
| 149 | |
| 150 RunBitExactnessTest(AudioProcessing::kSampleRate32kHz, CreateArrayGeometry(1), | |
| 151 TargetDirection1, kOutputReference); | |
| 152 } | |
| 153 | |
| 154 TEST(BeamformerBitExactnessTest, Stereo48kHz_ArrayGeometry1_TargetDirection1) { | |
| 155 const float kOutputReference[] = {0.000106f, -0.000464f, 0.000188f, | |
| 156 0.000106f, -0.000464f, 0.000188f}; | |
| 157 | |
| 158 RunBitExactnessTest(AudioProcessing::kSampleRate48kHz, CreateArrayGeometry(1), | |
| 159 TargetDirection1, kOutputReference); | |
| 160 } | |
| 161 | |
| 162 // TODO(peah): Investigate why the nonlinear_beamformer.cc causes a DCHECK in | |
| 163 // this setup. | |
| 164 TEST(BeamformerBitExactnessTest, | |
| 165 DISABLED_Stereo8kHz_ArrayGeometry1_TargetDirection2) { | |
| 166 const float kOutputReference[] = {0.001144f, -0.001026f, 0.001074f, | |
| 167 -0.016205f, -0.007324f, -0.015656f}; | |
| 168 | |
| 169 RunBitExactnessTest(AudioProcessing::kSampleRate8kHz, CreateArrayGeometry(1), | |
| 170 TargetDirection2, kOutputReference); | |
| 171 } | |
| 172 | |
| 173 TEST(BeamformerBitExactnessTest, Stereo16kHz_ArrayGeometry1_TargetDirection2) { | |
| 174 const float kOutputReference[] = {0.001144f, -0.001026f, 0.001074f, | |
| 175 0.001144f, -0.001026f, 0.001074f}; | |
| 176 | |
| 177 RunBitExactnessTest(AudioProcessing::kSampleRate16kHz, CreateArrayGeometry(1), | |
| 178 TargetDirection2, kOutputReference); | |
| 179 } | |
| 180 | |
| 181 TEST(BeamformerBitExactnessTest, Stereo32kHz_ArrayGeometry1_TargetDirection2) { | |
| 182 const float kOutputReference[] = {0.000732f, -0.000397f, 0.000610f, | |
| 183 0.000732f, -0.000397f, 0.000610f}; | |
| 184 | |
| 185 RunBitExactnessTest(AudioProcessing::kSampleRate32kHz, CreateArrayGeometry(1), | |
| 186 TargetDirection2, kOutputReference); | |
| 187 } | |
| 188 | |
| 189 TEST(BeamformerBitExactnessTest, Stereo48kHz_ArrayGeometry1_TargetDirection2) { | |
| 190 const float kOutputReference[] = {0.000106f, -0.000464f, 0.000188f, | |
| 191 0.000106f, -0.000464f, 0.000188f}; | |
| 192 | |
| 193 RunBitExactnessTest(AudioProcessing::kSampleRate48kHz, CreateArrayGeometry(1), | |
| 194 TargetDirection2, kOutputReference); | |
| 195 } | |
| 196 | |
| 197 TEST(BeamformerBitExactnessTest, Stereo8kHz_ArrayGeometry2_TargetDirection2) { | |
| 198 const float kOutputReference[] = {-0.000649f, 0.000576f, -0.000148f, | |
| 199 -0.000649f, 0.000576f, -0.000148f}; | |
| 200 | |
| 201 RunBitExactnessTest(AudioProcessing::kSampleRate8kHz, CreateArrayGeometry(2), | |
| 202 TargetDirection2, kOutputReference); | |
| 203 } | |
| 204 | |
| 205 TEST(BeamformerBitExactnessTest, Stereo16kHz_ArrayGeometry2_TargetDirection2) { | |
| 206 const float kOutputReference[] = {0.000808f, -0.000695f, 0.000739f, | |
| 207 0.000808f, -0.000695f, 0.000739f}; | |
| 208 | |
| 209 RunBitExactnessTest(AudioProcessing::kSampleRate16kHz, CreateArrayGeometry(2), | |
| 210 TargetDirection2, kOutputReference); | |
| 211 } | |
| 212 | |
| 213 TEST(BeamformerBitExactnessTest, Stereo32kHz_ArrayGeometry2_TargetDirection2) { | |
| 214 const float kOutputReference[] = {0.000580f, -0.000183f, 0.000458f, | |
| 215 0.000580f, -0.000183f, 0.000458f}; | |
| 216 | |
| 217 RunBitExactnessTest(AudioProcessing::kSampleRate32kHz, CreateArrayGeometry(2), | |
| 218 TargetDirection2, kOutputReference); | |
| 219 } | |
| 220 | |
| 221 TEST(BeamformerBitExactnessTest, Stereo48kHz_ArrayGeometry2_TargetDirection2) { | |
| 222 const float kOutputReference[] = {0.000075f, -0.000288f, 0.000156f, | |
| 223 0.000075f, -0.000288f, 0.000156f}; | |
| 224 | |
| 225 RunBitExactnessTest(AudioProcessing::kSampleRate48kHz, CreateArrayGeometry(2), | |
| 226 TargetDirection2, kOutputReference); | |
| 227 } | |
| 228 | |
| 229 TEST(BeamformerBitExactnessTest, Stereo8kHz_ArrayGeometry4_TargetDirection2) { | |
| 230 const float kOutputReference[] = {-0.000649f, 0.000576f, -0.000148f, | |
| 231 -0.000649f, 0.000576f, -0.000148f}; | |
| 232 | |
| 233 RunBitExactnessTest(AudioProcessing::kSampleRate8kHz, CreateArrayGeometry(2), | |
| 234 TargetDirection2, kOutputReference); | |
| 235 } | |
| 236 | |
| 237 TEST(BeamformerBitExactnessTest, Stereo16kHz_ArrayGeometry4_TargetDirection2) { | |
| 238 const float kOutputReference[] = {0.000808f, -0.000695f, 0.000739f, | |
| 239 0.000808f, -0.000695f, 0.000739f}; | |
| 240 | |
| 241 RunBitExactnessTest(AudioProcessing::kSampleRate16kHz, CreateArrayGeometry(2), | |
| 242 TargetDirection2, kOutputReference); | |
| 243 } | |
| 244 | |
| 245 TEST(BeamformerBitExactnessTest, Stereo32kHz_ArrayGeometry4_TargetDirection2) { | |
| 246 const float kOutputReference[] = {0.000580f, -0.000183f, 0.000458f, | |
| 247 0.000580f, -0.000183f, 0.000458f}; | |
| 248 | |
| 249 RunBitExactnessTest(AudioProcessing::kSampleRate32kHz, CreateArrayGeometry(2), | |
| 250 TargetDirection2, kOutputReference); | |
| 251 } | |
| 252 | |
| 253 TEST(BeamformerBitExactnessTest, Stereo48kHz_ArrayGeometry4_TargetDirection2) { | |
| 254 const float kOutputReference[] = {0.000075f, -0.000288f, 0.000156f, | |
| 255 0.000075f, -0.000288f, 0.000156f}; | |
| 256 | |
| 257 RunBitExactnessTest(AudioProcessing::kSampleRate48kHz, CreateArrayGeometry(2), | |
| 258 TargetDirection2, kOutputReference); | |
| 259 } | |
| 260 | |
| 261 // TODO(peah): Investigate why the nonlinear_beamformer.cc causes a DCHECK in | |
| 262 // this setup. | |
| 263 TEST(BeamformerBitExactnessTest, | |
| 264 DISABLED_Stereo16kHz_ArrayGeometry3_TargetDirection1) { | |
| 265 const float kOutputReference[] = {-0.000161f, 0.000171f, -0.000096f, | |
| 266 0.001007f, 0.000427f, 0.000977f}; | |
| 267 | |
| 268 RunBitExactnessTest(AudioProcessing::kSampleRate16kHz, CreateArrayGeometry(3), | |
| 269 TargetDirection1, kOutputReference); | |
| 270 } | |
| 271 | |
| 272 } // namespace webrtc | |
| OLD | NEW |