OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 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 #include <memory> | 11 #include <memory> |
12 | 12 |
13 #include "webrtc/common_audio/blocker.h" | 13 #include "webrtc/modules/audio_processing/utility/blocker.h" |
14 | 14 |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 #include "webrtc/base/arraysize.h" | 16 #include "webrtc/base/arraysize.h" |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 // Callback Function to add 3 to every sample in the signal. | 20 // Callback Function to add 3 to every sample in the signal. |
21 class PlusThreeBlockerCallback : public webrtc::BlockerCallback { | 21 class PlusThreeBlockerCallback : public webrtc::BlockerCallback { |
22 public: | 22 public: |
23 void ProcessBlock(const float* const* input, | 23 void ProcessBlock(const float* const* input, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 const float* const* input, | 64 const float* const* input, |
65 float* const* input_chunk, | 65 float* const* input_chunk, |
66 float* const* output, | 66 float* const* output, |
67 float* const* output_chunk, | 67 float* const* output_chunk, |
68 size_t num_input_channels, | 68 size_t num_input_channels, |
69 size_t num_output_channels) { | 69 size_t num_output_channels) { |
70 size_t start = 0; | 70 size_t start = 0; |
71 size_t end = chunk_size - 1; | 71 size_t end = chunk_size - 1; |
72 while (end < num_frames) { | 72 while (end < num_frames) { |
73 CopyTo(input_chunk, 0, start, num_input_channels, chunk_size, input); | 73 CopyTo(input_chunk, 0, start, num_input_channels, chunk_size, input); |
74 blocker->ProcessChunk(input_chunk, | 74 blocker->ProcessChunk(input_chunk, chunk_size, num_input_channels, |
75 chunk_size, | 75 num_output_channels, output_chunk); |
76 num_input_channels, | |
77 num_output_channels, | |
78 output_chunk); | |
79 CopyTo(output, start, 0, num_output_channels, chunk_size, output_chunk); | 76 CopyTo(output, start, 0, num_output_channels, chunk_size, output_chunk); |
80 | 77 |
81 start += chunk_size; | 78 start += chunk_size; |
82 end += chunk_size; | 79 end += chunk_size; |
83 } | 80 } |
84 } | 81 } |
85 | 82 |
86 void ValidateSignalEquality(const float* const* expected, | 83 void ValidateSignalEquality(const float* const* expected, |
87 const float* const* actual, | 84 const float* const* actual, |
88 size_t num_channels, | 85 size_t num_channels, |
(...skipping 20 matching lines...) Expand all Loading... |
109 } | 106 } |
110 } | 107 } |
111 | 108 |
112 static void CopyTo(float* const* dst, | 109 static void CopyTo(float* const* dst, |
113 size_t start_index_dst, | 110 size_t start_index_dst, |
114 size_t start_index_src, | 111 size_t start_index_src, |
115 size_t num_channels, | 112 size_t num_channels, |
116 size_t num_frames, | 113 size_t num_frames, |
117 const float* const* src) { | 114 const float* const* src) { |
118 for (size_t i = 0; i < num_channels; ++i) { | 115 for (size_t i = 0; i < num_channels; ++i) { |
119 memcpy(&dst[i][start_index_dst], | 116 memcpy(&dst[i][start_index_dst], &src[i][start_index_src], |
120 &src[i][start_index_src], | |
121 num_frames * sizeof(float)); | 117 num_frames * sizeof(float)); |
122 } | 118 } |
123 } | 119 } |
124 }; | 120 }; |
125 | 121 |
126 TEST_F(BlockerTest, TestBlockerMutuallyPrimeChunkandBlockSize) { | 122 TEST_F(BlockerTest, TestBlockerMutuallyPrimeChunkandBlockSize) { |
127 const size_t kNumInputChannels = 3; | 123 const size_t kNumInputChannels = 3; |
128 const size_t kNumOutputChannels = 2; | 124 const size_t kNumOutputChannels = 2; |
129 const size_t kNumFrames = 10; | 125 const size_t kNumFrames = 10; |
130 const size_t kBlockSize = 4; | 126 const size_t kBlockSize = 4; |
(...skipping 14 matching lines...) Expand all Loading... |
145 expected_output_cb.SetDataForTesting( | 141 expected_output_cb.SetDataForTesting( |
146 kExpectedOutput[0], sizeof(kExpectedOutput) / sizeof(**kExpectedOutput)); | 142 kExpectedOutput[0], sizeof(kExpectedOutput) / sizeof(**kExpectedOutput)); |
147 | 143 |
148 const float kWindow[kBlockSize] = {2.f, 2.f, 2.f, 2.f}; | 144 const float kWindow[kBlockSize] = {2.f, 2.f, 2.f, 2.f}; |
149 | 145 |
150 ChannelBuffer<float> actual_output_cb(kNumFrames, kNumOutputChannels); | 146 ChannelBuffer<float> actual_output_cb(kNumFrames, kNumOutputChannels); |
151 ChannelBuffer<float> input_chunk_cb(kChunkSize, kNumInputChannels); | 147 ChannelBuffer<float> input_chunk_cb(kChunkSize, kNumInputChannels); |
152 ChannelBuffer<float> output_chunk_cb(kChunkSize, kNumOutputChannels); | 148 ChannelBuffer<float> output_chunk_cb(kChunkSize, kNumOutputChannels); |
153 | 149 |
154 PlusThreeBlockerCallback callback; | 150 PlusThreeBlockerCallback callback; |
155 Blocker blocker(kChunkSize, | 151 Blocker blocker(kChunkSize, kBlockSize, kNumInputChannels, kNumOutputChannels, |
156 kBlockSize, | 152 kWindow, kShiftAmount, &callback); |
157 kNumInputChannels, | |
158 kNumOutputChannels, | |
159 kWindow, | |
160 kShiftAmount, | |
161 &callback); | |
162 | 153 |
163 RunTest(&blocker, | 154 RunTest(&blocker, kChunkSize, kNumFrames, input_cb.channels(), |
164 kChunkSize, | 155 input_chunk_cb.channels(), actual_output_cb.channels(), |
165 kNumFrames, | 156 output_chunk_cb.channels(), kNumInputChannels, kNumOutputChannels); |
166 input_cb.channels(), | |
167 input_chunk_cb.channels(), | |
168 actual_output_cb.channels(), | |
169 output_chunk_cb.channels(), | |
170 kNumInputChannels, | |
171 kNumOutputChannels); | |
172 | 157 |
173 ValidateSignalEquality(expected_output_cb.channels(), | 158 ValidateSignalEquality(expected_output_cb.channels(), |
174 actual_output_cb.channels(), | 159 actual_output_cb.channels(), kNumOutputChannels, |
175 kNumOutputChannels, | |
176 kNumFrames); | 160 kNumFrames); |
177 } | 161 } |
178 | 162 |
179 TEST_F(BlockerTest, TestBlockerMutuallyPrimeShiftAndBlockSize) { | 163 TEST_F(BlockerTest, TestBlockerMutuallyPrimeShiftAndBlockSize) { |
180 const size_t kNumInputChannels = 3; | 164 const size_t kNumInputChannels = 3; |
181 const size_t kNumOutputChannels = 2; | 165 const size_t kNumOutputChannels = 2; |
182 const size_t kNumFrames = 12; | 166 const size_t kNumFrames = 12; |
183 const size_t kBlockSize = 4; | 167 const size_t kBlockSize = 4; |
184 const size_t kChunkSize = 6; | 168 const size_t kChunkSize = 6; |
185 const size_t kShiftAmount = 3; | 169 const size_t kShiftAmount = 3; |
(...skipping 12 matching lines...) Expand all Loading... |
198 expected_output_cb.SetDataForTesting( | 182 expected_output_cb.SetDataForTesting( |
199 kExpectedOutput[0], sizeof(kExpectedOutput) / sizeof(**kExpectedOutput)); | 183 kExpectedOutput[0], sizeof(kExpectedOutput) / sizeof(**kExpectedOutput)); |
200 | 184 |
201 const float kWindow[kBlockSize] = {2.f, 2.f, 2.f, 2.f}; | 185 const float kWindow[kBlockSize] = {2.f, 2.f, 2.f, 2.f}; |
202 | 186 |
203 ChannelBuffer<float> actual_output_cb(kNumFrames, kNumOutputChannels); | 187 ChannelBuffer<float> actual_output_cb(kNumFrames, kNumOutputChannels); |
204 ChannelBuffer<float> input_chunk_cb(kChunkSize, kNumInputChannels); | 188 ChannelBuffer<float> input_chunk_cb(kChunkSize, kNumInputChannels); |
205 ChannelBuffer<float> output_chunk_cb(kChunkSize, kNumOutputChannels); | 189 ChannelBuffer<float> output_chunk_cb(kChunkSize, kNumOutputChannels); |
206 | 190 |
207 PlusThreeBlockerCallback callback; | 191 PlusThreeBlockerCallback callback; |
208 Blocker blocker(kChunkSize, | 192 Blocker blocker(kChunkSize, kBlockSize, kNumInputChannels, kNumOutputChannels, |
209 kBlockSize, | 193 kWindow, kShiftAmount, &callback); |
210 kNumInputChannels, | |
211 kNumOutputChannels, | |
212 kWindow, | |
213 kShiftAmount, | |
214 &callback); | |
215 | 194 |
216 RunTest(&blocker, | 195 RunTest(&blocker, kChunkSize, kNumFrames, input_cb.channels(), |
217 kChunkSize, | 196 input_chunk_cb.channels(), actual_output_cb.channels(), |
218 kNumFrames, | 197 output_chunk_cb.channels(), kNumInputChannels, kNumOutputChannels); |
219 input_cb.channels(), | |
220 input_chunk_cb.channels(), | |
221 actual_output_cb.channels(), | |
222 output_chunk_cb.channels(), | |
223 kNumInputChannels, | |
224 kNumOutputChannels); | |
225 | 198 |
226 ValidateSignalEquality(expected_output_cb.channels(), | 199 ValidateSignalEquality(expected_output_cb.channels(), |
227 actual_output_cb.channels(), | 200 actual_output_cb.channels(), kNumOutputChannels, |
228 kNumOutputChannels, | |
229 kNumFrames); | 201 kNumFrames); |
230 } | 202 } |
231 | 203 |
232 TEST_F(BlockerTest, TestBlockerNoOverlap) { | 204 TEST_F(BlockerTest, TestBlockerNoOverlap) { |
233 const size_t kNumInputChannels = 3; | 205 const size_t kNumInputChannels = 3; |
234 const size_t kNumOutputChannels = 2; | 206 const size_t kNumOutputChannels = 2; |
235 const size_t kNumFrames = 12; | 207 const size_t kNumFrames = 12; |
236 const size_t kBlockSize = 4; | 208 const size_t kBlockSize = 4; |
237 const size_t kChunkSize = 4; | 209 const size_t kChunkSize = 4; |
238 const size_t kShiftAmount = 4; | 210 const size_t kShiftAmount = 4; |
(...skipping 12 matching lines...) Expand all Loading... |
251 expected_output_cb.SetDataForTesting( | 223 expected_output_cb.SetDataForTesting( |
252 kExpectedOutput[0], sizeof(kExpectedOutput) / sizeof(**kExpectedOutput)); | 224 kExpectedOutput[0], sizeof(kExpectedOutput) / sizeof(**kExpectedOutput)); |
253 | 225 |
254 const float kWindow[kBlockSize] = {2.f, 2.f, 2.f, 2.f}; | 226 const float kWindow[kBlockSize] = {2.f, 2.f, 2.f, 2.f}; |
255 | 227 |
256 ChannelBuffer<float> actual_output_cb(kNumFrames, kNumOutputChannels); | 228 ChannelBuffer<float> actual_output_cb(kNumFrames, kNumOutputChannels); |
257 ChannelBuffer<float> input_chunk_cb(kChunkSize, kNumInputChannels); | 229 ChannelBuffer<float> input_chunk_cb(kChunkSize, kNumInputChannels); |
258 ChannelBuffer<float> output_chunk_cb(kChunkSize, kNumOutputChannels); | 230 ChannelBuffer<float> output_chunk_cb(kChunkSize, kNumOutputChannels); |
259 | 231 |
260 PlusThreeBlockerCallback callback; | 232 PlusThreeBlockerCallback callback; |
261 Blocker blocker(kChunkSize, | 233 Blocker blocker(kChunkSize, kBlockSize, kNumInputChannels, kNumOutputChannels, |
262 kBlockSize, | 234 kWindow, kShiftAmount, &callback); |
263 kNumInputChannels, | |
264 kNumOutputChannels, | |
265 kWindow, | |
266 kShiftAmount, | |
267 &callback); | |
268 | 235 |
269 RunTest(&blocker, | 236 RunTest(&blocker, kChunkSize, kNumFrames, input_cb.channels(), |
270 kChunkSize, | 237 input_chunk_cb.channels(), actual_output_cb.channels(), |
271 kNumFrames, | 238 output_chunk_cb.channels(), kNumInputChannels, kNumOutputChannels); |
272 input_cb.channels(), | |
273 input_chunk_cb.channels(), | |
274 actual_output_cb.channels(), | |
275 output_chunk_cb.channels(), | |
276 kNumInputChannels, | |
277 kNumOutputChannels); | |
278 | 239 |
279 ValidateSignalEquality(expected_output_cb.channels(), | 240 ValidateSignalEquality(expected_output_cb.channels(), |
280 actual_output_cb.channels(), | 241 actual_output_cb.channels(), kNumOutputChannels, |
281 kNumOutputChannels, | |
282 kNumFrames); | 242 kNumFrames); |
283 } | 243 } |
284 | 244 |
285 TEST_F(BlockerTest, InitialDelaysAreMinimum) { | 245 TEST_F(BlockerTest, InitialDelaysAreMinimum) { |
286 const size_t kNumInputChannels = 3; | 246 const size_t kNumInputChannels = 3; |
287 const size_t kNumOutputChannels = 2; | 247 const size_t kNumOutputChannels = 2; |
288 const size_t kNumFrames = 1280; | 248 const size_t kNumFrames = 1280; |
289 const size_t kChunkSize[] = | 249 const size_t kChunkSize[] = {80, 80, 80, 80, 80, 80, |
290 {80, 80, 80, 80, 80, 80, 160, 160, 160, 160, 160, 160}; | 250 160, 160, 160, 160, 160, 160}; |
291 const size_t kBlockSize[] = | 251 const size_t kBlockSize[] = {64, 64, 64, 128, 128, 128, |
292 {64, 64, 64, 128, 128, 128, 128, 128, 128, 256, 256, 256}; | 252 128, 128, 128, 256, 256, 256}; |
293 const size_t kShiftAmount[] = | 253 const size_t kShiftAmount[] = {16, 32, 64, 32, 64, 128, |
294 {16, 32, 64, 32, 64, 128, 32, 64, 128, 64, 128, 256}; | 254 32, 64, 128, 64, 128, 256}; |
295 const size_t kInitialDelay[] = | 255 const size_t kInitialDelay[] = {48, 48, 48, 112, 112, 112, |
296 {48, 48, 48, 112, 112, 112, 96, 96, 96, 224, 224, 224}; | 256 96, 96, 96, 224, 224, 224}; |
297 | 257 |
298 float input[kNumInputChannels][kNumFrames]; | 258 float input[kNumInputChannels][kNumFrames]; |
299 for (size_t i = 0; i < kNumInputChannels; ++i) { | 259 for (size_t i = 0; i < kNumInputChannels; ++i) { |
300 for (size_t j = 0; j < kNumFrames; ++j) { | 260 for (size_t j = 0; j < kNumFrames; ++j) { |
301 input[i][j] = i + 1; | 261 input[i][j] = i + 1; |
302 } | 262 } |
303 } | 263 } |
304 ChannelBuffer<float> input_cb(kNumFrames, kNumInputChannels); | 264 ChannelBuffer<float> input_cb(kNumFrames, kNumInputChannels); |
305 input_cb.SetDataForTesting(input[0], sizeof(input) / sizeof(**input)); | 265 input_cb.SetDataForTesting(input[0], sizeof(input) / sizeof(**input)); |
306 | 266 |
307 ChannelBuffer<float> output_cb(kNumFrames, kNumOutputChannels); | 267 ChannelBuffer<float> output_cb(kNumFrames, kNumOutputChannels); |
308 | 268 |
309 CopyBlockerCallback callback; | 269 CopyBlockerCallback callback; |
310 | 270 |
311 for (size_t i = 0; i < arraysize(kChunkSize); ++i) { | 271 for (size_t i = 0; i < arraysize(kChunkSize); ++i) { |
312 std::unique_ptr<float[]> window(new float[kBlockSize[i]]); | 272 std::unique_ptr<float[]> window(new float[kBlockSize[i]]); |
313 for (size_t j = 0; j < kBlockSize[i]; ++j) { | 273 for (size_t j = 0; j < kBlockSize[i]; ++j) { |
314 window[j] = 1.f; | 274 window[j] = 1.f; |
315 } | 275 } |
316 | 276 |
317 ChannelBuffer<float> input_chunk_cb(kChunkSize[i], kNumInputChannels); | 277 ChannelBuffer<float> input_chunk_cb(kChunkSize[i], kNumInputChannels); |
318 ChannelBuffer<float> output_chunk_cb(kChunkSize[i], kNumOutputChannels); | 278 ChannelBuffer<float> output_chunk_cb(kChunkSize[i], kNumOutputChannels); |
319 | 279 |
320 Blocker blocker(kChunkSize[i], | 280 Blocker blocker(kChunkSize[i], kBlockSize[i], kNumInputChannels, |
321 kBlockSize[i], | 281 kNumOutputChannels, window.get(), kShiftAmount[i], |
322 kNumInputChannels, | |
323 kNumOutputChannels, | |
324 window.get(), | |
325 kShiftAmount[i], | |
326 &callback); | 282 &callback); |
327 | 283 |
328 RunTest(&blocker, | 284 RunTest(&blocker, kChunkSize[i], kNumFrames, input_cb.channels(), |
329 kChunkSize[i], | 285 input_chunk_cb.channels(), output_cb.channels(), |
330 kNumFrames, | 286 output_chunk_cb.channels(), kNumInputChannels, kNumOutputChannels); |
331 input_cb.channels(), | |
332 input_chunk_cb.channels(), | |
333 output_cb.channels(), | |
334 output_chunk_cb.channels(), | |
335 kNumInputChannels, | |
336 kNumOutputChannels); | |
337 | 287 |
338 ValidateInitialDelay(output_cb.channels(), | 288 ValidateInitialDelay(output_cb.channels(), kNumOutputChannels, kNumFrames, |
339 kNumOutputChannels, | |
340 kNumFrames, | |
341 kInitialDelay[i]); | 289 kInitialDelay[i]); |
342 } | 290 } |
343 } | 291 } |
344 | 292 |
345 } // namespace webrtc | 293 } // namespace webrtc |
OLD | NEW |