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/echo_control_mobile_impl.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 // TODO(peah): Increase the number of frames to proces when the issue of | |
23 // non repeatable test results have been found. | |
24 const int kNumFramesToProcess = 200; | |
25 | |
26 void SetupComponent(int sample_rate_hz, | |
27 EchoControlMobile::RoutingMode routing_mode, | |
28 bool comfort_noise_enabled, | |
29 EchoControlMobileImpl* echo_control_mobile) { | |
30 echo_control_mobile->Initialize( | |
31 sample_rate_hz > 16000 ? 16000 : sample_rate_hz, 1, 1); | |
32 EchoControlMobile* ec = static_cast<EchoControlMobile*>(echo_control_mobile); | |
33 ec->Enable(true); | |
34 ec->set_routing_mode(routing_mode); | |
35 ec->enable_comfort_noise(comfort_noise_enabled); | |
36 } | |
37 | |
38 void ProcessOneFrame(int sample_rate_hz, | |
39 int stream_delay_ms, | |
40 AudioBuffer* render_audio_buffer, | |
41 AudioBuffer* capture_audio_buffer, | |
42 EchoControlMobileImpl* echo_control_mobile) { | |
43 if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) { | |
44 render_audio_buffer->SplitIntoFrequencyBands(); | |
45 capture_audio_buffer->SplitIntoFrequencyBands(); | |
46 } | |
47 | |
48 echo_control_mobile->ProcessRenderAudio(render_audio_buffer); | |
49 echo_control_mobile->ProcessCaptureAudio(capture_audio_buffer, | |
50 stream_delay_ms); | |
51 | |
52 if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) { | |
53 capture_audio_buffer->MergeFrequencyBands(); | |
54 } | |
55 } | |
56 | |
57 void RunBitexactnessTest(int sample_rate_hz, | |
58 size_t num_channels, | |
59 int stream_delay_ms, | |
60 EchoControlMobile::RoutingMode routing_mode, | |
61 bool comfort_noise_enabled, | |
62 const rtc::ArrayView<const float>& output_reference) { | |
63 rtc::CriticalSection crit_render; | |
64 rtc::CriticalSection crit_capture; | |
65 EchoControlMobileImpl echo_control_mobile(&crit_render, &crit_capture); | |
66 SetupComponent(sample_rate_hz, routing_mode, comfort_noise_enabled, | |
67 &echo_control_mobile); | |
68 | |
69 const int samples_per_channel = rtc::CheckedDivExact(sample_rate_hz, 100); | |
70 const StreamConfig render_config(sample_rate_hz, num_channels, false); | |
71 AudioBuffer render_buffer( | |
72 render_config.num_frames(), render_config.num_channels(), | |
73 render_config.num_frames(), 1, render_config.num_frames()); | |
74 test::InputAudioFile render_file( | |
75 test::GetApmRenderTestVectorFileName(sample_rate_hz)); | |
76 std::vector<float> render_input(samples_per_channel * num_channels); | |
77 | |
78 const StreamConfig capture_config(sample_rate_hz, num_channels, false); | |
79 AudioBuffer capture_buffer( | |
80 capture_config.num_frames(), capture_config.num_channels(), | |
81 capture_config.num_frames(), 1, capture_config.num_frames()); | |
82 test::InputAudioFile capture_file( | |
83 test::GetApmCaptureTestVectorFileName(sample_rate_hz)); | |
84 std::vector<float> capture_input(samples_per_channel * num_channels); | |
85 | |
86 for (int frame_no = 0; frame_no < kNumFramesToProcess; ++frame_no) { | |
87 ReadFloatSamplesFromStereoFile(samples_per_channel, num_channels, | |
88 &render_file, render_input); | |
89 ReadFloatSamplesFromStereoFile(samples_per_channel, num_channels, | |
90 &capture_file, capture_input); | |
91 | |
92 test::CopyVectorToAudioBuffer(render_config, render_input, &render_buffer); | |
93 test::CopyVectorToAudioBuffer(capture_config, capture_input, | |
94 &capture_buffer); | |
95 | |
96 ProcessOneFrame(sample_rate_hz, stream_delay_ms, &render_buffer, | |
97 &capture_buffer, &echo_control_mobile); | |
98 } | |
99 | |
100 // Extract and verify the test results. | |
101 std::vector<float> capture_output; | |
102 test::ExtractVectorFromAudioBuffer(capture_config, &capture_buffer, | |
103 &capture_output); | |
104 | |
105 // Compare the output with the reference. Only the first values of the output | |
106 // from last frame processed are compared in order not having to specify all | |
107 // preceeding frames as testvectors. As the algorithm being tested has a | |
108 // memory, testing only the last frame implicitly also tests the preceeding | |
109 // frames. | |
110 const float kTolerance = 1.0f / 32768.0f; | |
111 EXPECT_TRUE(test::BitExactFrame( | |
112 capture_config.num_frames(), capture_config.num_channels(), | |
113 output_reference, capture_output, kTolerance)); | |
114 } | |
115 | |
116 } // namespace | |
117 | |
118 // TODO(peah): Renable once the integer overflow issue in aecm_core.c:932:69 | |
119 // has been solved. | |
120 TEST(EchoControlMobileBitExactnessTest, | |
121 DISABLED_Mono8kHz_LoudSpeakerPhone_CngOn_StreamDelay0) { | |
122 const float kOutputReference[] = {0.005280f, 0.002380f, -0.000427f}; | |
123 | |
124 RunBitexactnessTest(8000, 1, 0, | |
125 EchoControlMobile::RoutingMode::kLoudSpeakerphone, true, | |
126 kOutputReference); | |
127 } | |
128 | |
129 TEST(EchoControlMobileBitExactnessTest, | |
130 DISABLED_Mono16kHz_LoudSpeakerPhone_CngOn_StreamDelay0) { | |
131 const float kOutputReference[] = {0.003601f, 0.002991f, 0.001923f}; | |
132 RunBitexactnessTest(16000, 1, 0, | |
133 EchoControlMobile::RoutingMode::kLoudSpeakerphone, true, | |
134 kOutputReference); | |
135 } | |
136 | |
137 TEST(EchoControlMobileBitExactnessTest, | |
138 DISABLED_Mono32kHz_LoudSpeakerPhone_CngOn_StreamDelay0) { | |
139 const float kOutputReference[] = {0.002258f, 0.002899f, 0.003906f}; | |
140 | |
141 RunBitexactnessTest(32000, 1, 0, | |
142 EchoControlMobile::RoutingMode::kLoudSpeakerphone, true, | |
143 kOutputReference); | |
144 } | |
145 | |
146 TEST(EchoControlMobileBitExactnessTest, | |
147 DISABLED_Mono48kHz_LoudSpeakerPhone_CngOn_StreamDelay0) { | |
148 const float kOutputReference[] = {-0.000046f, 0.000041f, 0.000249f}; | |
149 | |
150 RunBitexactnessTest(48000, 1, 0, | |
151 EchoControlMobile::RoutingMode::kLoudSpeakerphone, true, | |
152 kOutputReference); | |
153 } | |
154 | |
155 TEST(EchoControlMobileBitExactnessTest, | |
156 DISABLED_Mono16kHz_LoudSpeakerPhone_CngOff_StreamDelay0) { | |
157 const float kOutputReference[] = {0.000000f, 0.000000f, 0.000000f}; | |
158 | |
159 RunBitexactnessTest(16000, 1, 0, | |
160 EchoControlMobile::RoutingMode::kLoudSpeakerphone, false, | |
161 kOutputReference); | |
162 } | |
163 | |
164 // TODO(peah): Renable once the integer overflow issue in aecm_core.c:932:69 | |
165 // has been solved. | |
166 TEST(EchoControlMobileBitExactnessTest, | |
167 DISABLED_Mono16kHz_LoudSpeakerPhone_CngOn_StreamDelay5) { | |
168 const float kOutputReference[] = {0.003693f, 0.002930f, 0.001801f}; | |
169 | |
170 RunBitexactnessTest(16000, 1, 5, | |
171 EchoControlMobile::RoutingMode::kLoudSpeakerphone, true, | |
172 kOutputReference); | |
173 } | |
174 | |
175 TEST(EchoControlMobileBitExactnessTest, | |
176 Mono16kHz_LoudSpeakerPhone_CngOn_StreamDelay10) { | |
177 const float kOutputReference[] = {-0.002411f, -0.002716f, -0.002747f}; | |
178 | |
179 RunBitexactnessTest(16000, 1, 10, | |
180 EchoControlMobile::RoutingMode::kLoudSpeakerphone, true, | |
181 kOutputReference); | |
182 } | |
183 | |
184 TEST(EchoControlMobileBitExactnessTest, | |
185 DISABLED_Mono16kHz_QuietEarpieceOrHeadset_CngOn_StreamDelay0) { | |
186 const float kOutputReference[] = {0.000397f, 0.000000f, -0.000305f}; | |
187 | |
188 RunBitexactnessTest(16000, 1, 0, | |
189 EchoControlMobile::RoutingMode::kQuietEarpieceOrHeadset, | |
190 true, kOutputReference); | |
191 } | |
192 | |
193 TEST(EchoControlMobileBitExactnessTest, | |
194 DISABLED_Mono16kHz_Earpiece_CngOn_StreamDelay0) { | |
195 const float kOutputReference[] = {0.002167f, 0.001617f, 0.001038f}; | |
196 | |
197 RunBitexactnessTest(16000, 1, 0, EchoControlMobile::RoutingMode::kEarpiece, | |
198 true, kOutputReference); | |
199 } | |
200 | |
201 TEST(EchoControlMobileBitExactnessTest, | |
202 DISABLED_Mono16kHz_LoudEarpiece_CngOn_StreamDelay0) { | |
203 const float kOutputReference[] = {0.003540f, 0.002899f, 0.001862f}; | |
204 | |
205 RunBitexactnessTest(16000, 1, 0, | |
206 EchoControlMobile::RoutingMode::kLoudEarpiece, true, | |
207 kOutputReference); | |
208 } | |
209 | |
210 TEST(EchoControlMobileBitExactnessTest, | |
211 DISABLED_Mono16kHz_SpeakerPhone_CngOn_StreamDelay0) { | |
212 const float kOutputReference[] = {0.003632f, 0.003052f, 0.001984f}; | |
213 | |
214 RunBitexactnessTest(16000, 1, 0, | |
215 EchoControlMobile::RoutingMode::kSpeakerphone, true, | |
216 kOutputReference); | |
217 } | |
218 | |
219 } // namespace webrtc | |
OLD | NEW |