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 "webrtc/common_audio/blocker.h" | 11 #include "webrtc/common_audio/blocker.h" |
12 | 12 |
13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
14 #include "webrtc/base/arraysize.h" | 14 #include "webrtc/base/arraysize.h" |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 // Callback Function to add 3 to every sample in the signal. | 18 // Callback Function to add 3 to every sample in the signal. |
19 class PlusThreeBlockerCallback : public webrtc::BlockerCallback { | 19 class PlusThreeBlockerCallback : public webrtc::BlockerCallback { |
20 public: | 20 public: |
21 void ProcessBlock(const float* const* input, | 21 void ProcessBlock(const float* const* input, |
22 size_t num_frames, | 22 size_t num_frames, |
23 int num_input_channels, | 23 size_t num_input_channels, |
24 int num_output_channels, | 24 size_t num_output_channels, |
25 float* const* output) override { | 25 float* const* output) override { |
26 for (int i = 0; i < num_output_channels; ++i) { | 26 for (size_t i = 0; i < num_output_channels; ++i) { |
27 for (size_t j = 0; j < num_frames; ++j) { | 27 for (size_t j = 0; j < num_frames; ++j) { |
28 output[i][j] = input[i][j] + 3; | 28 output[i][j] = input[i][j] + 3; |
29 } | 29 } |
30 } | 30 } |
31 } | 31 } |
32 }; | 32 }; |
33 | 33 |
34 // No-op Callback Function. | 34 // No-op Callback Function. |
35 class CopyBlockerCallback : public webrtc::BlockerCallback { | 35 class CopyBlockerCallback : public webrtc::BlockerCallback { |
36 public: | 36 public: |
37 void ProcessBlock(const float* const* input, | 37 void ProcessBlock(const float* const* input, |
38 size_t num_frames, | 38 size_t num_frames, |
39 int num_input_channels, | 39 size_t num_input_channels, |
40 int num_output_channels, | 40 size_t num_output_channels, |
41 float* const* output) override { | 41 float* const* output) override { |
42 for (int i = 0; i < num_output_channels; ++i) { | 42 for (size_t i = 0; i < num_output_channels; ++i) { |
43 for (size_t j = 0; j < num_frames; ++j) { | 43 for (size_t j = 0; j < num_frames; ++j) { |
44 output[i][j] = input[i][j]; | 44 output[i][j] = input[i][j]; |
45 } | 45 } |
46 } | 46 } |
47 } | 47 } |
48 }; | 48 }; |
49 | 49 |
50 } // namespace | 50 } // namespace |
51 | 51 |
52 namespace webrtc { | 52 namespace webrtc { |
53 | 53 |
54 // Tests blocking with a window that multiplies the signal by 2, a callback | 54 // Tests blocking with a window that multiplies the signal by 2, a callback |
55 // that adds 3 to each sample in the signal, and different combinations of chunk | 55 // that adds 3 to each sample in the signal, and different combinations of chunk |
56 // size, block size, and shift amount. | 56 // size, block size, and shift amount. |
57 class BlockerTest : public ::testing::Test { | 57 class BlockerTest : public ::testing::Test { |
58 protected: | 58 protected: |
59 void RunTest(Blocker* blocker, | 59 void RunTest(Blocker* blocker, |
60 size_t chunk_size, | 60 size_t chunk_size, |
61 size_t num_frames, | 61 size_t num_frames, |
62 const float* const* input, | 62 const float* const* input, |
63 float* const* input_chunk, | 63 float* const* input_chunk, |
64 float* const* output, | 64 float* const* output, |
65 float* const* output_chunk, | 65 float* const* output_chunk, |
66 int num_input_channels, | 66 size_t num_input_channels, |
67 int num_output_channels) { | 67 size_t num_output_channels) { |
68 size_t start = 0; | 68 size_t start = 0; |
69 size_t end = chunk_size - 1; | 69 size_t end = chunk_size - 1; |
70 while (end < num_frames) { | 70 while (end < num_frames) { |
71 CopyTo(input_chunk, 0, start, num_input_channels, chunk_size, input); | 71 CopyTo(input_chunk, 0, start, num_input_channels, chunk_size, input); |
72 blocker->ProcessChunk(input_chunk, | 72 blocker->ProcessChunk(input_chunk, |
73 chunk_size, | 73 chunk_size, |
74 num_input_channels, | 74 num_input_channels, |
75 num_output_channels, | 75 num_output_channels, |
76 output_chunk); | 76 output_chunk); |
77 CopyTo(output, start, 0, num_output_channels, chunk_size, output_chunk); | 77 CopyTo(output, start, 0, num_output_channels, chunk_size, output_chunk); |
78 | 78 |
79 start += chunk_size; | 79 start += chunk_size; |
80 end += chunk_size; | 80 end += chunk_size; |
81 } | 81 } |
82 } | 82 } |
83 | 83 |
84 void ValidateSignalEquality(const float* const* expected, | 84 void ValidateSignalEquality(const float* const* expected, |
85 const float* const* actual, | 85 const float* const* actual, |
86 int num_channels, | 86 size_t num_channels, |
87 size_t num_frames) { | 87 size_t num_frames) { |
88 for (int i = 0; i < num_channels; ++i) { | 88 for (size_t i = 0; i < num_channels; ++i) { |
89 for (size_t j = 0; j < num_frames; ++j) { | 89 for (size_t j = 0; j < num_frames; ++j) { |
90 EXPECT_FLOAT_EQ(expected[i][j], actual[i][j]); | 90 EXPECT_FLOAT_EQ(expected[i][j], actual[i][j]); |
91 } | 91 } |
92 } | 92 } |
93 } | 93 } |
94 | 94 |
95 void ValidateInitialDelay(const float* const* output, | 95 void ValidateInitialDelay(const float* const* output, |
96 int num_channels, | 96 size_t num_channels, |
97 size_t num_frames, | 97 size_t num_frames, |
98 size_t initial_delay) { | 98 size_t initial_delay) { |
99 for (int i = 0; i < num_channels; ++i) { | 99 for (size_t i = 0; i < num_channels; ++i) { |
100 for (size_t j = 0; j < num_frames; ++j) { | 100 for (size_t j = 0; j < num_frames; ++j) { |
101 if (j < initial_delay) { | 101 if (j < initial_delay) { |
102 EXPECT_FLOAT_EQ(output[i][j], 0.f); | 102 EXPECT_FLOAT_EQ(output[i][j], 0.f); |
103 } else { | 103 } else { |
104 EXPECT_GT(output[i][j], 0.f); | 104 EXPECT_GT(output[i][j], 0.f); |
105 } | 105 } |
106 } | 106 } |
107 } | 107 } |
108 } | 108 } |
109 | 109 |
110 static void CopyTo(float* const* dst, | 110 static void CopyTo(float* const* dst, |
111 size_t start_index_dst, | 111 size_t start_index_dst, |
112 size_t start_index_src, | 112 size_t start_index_src, |
113 int num_channels, | 113 size_t num_channels, |
114 size_t num_frames, | 114 size_t num_frames, |
115 const float* const* src) { | 115 const float* const* src) { |
116 for (int i = 0; i < num_channels; ++i) { | 116 for (size_t i = 0; i < num_channels; ++i) { |
117 memcpy(&dst[i][start_index_dst], | 117 memcpy(&dst[i][start_index_dst], |
118 &src[i][start_index_src], | 118 &src[i][start_index_src], |
119 num_frames * sizeof(float)); | 119 num_frames * sizeof(float)); |
120 } | 120 } |
121 } | 121 } |
122 }; | 122 }; |
123 | 123 |
124 TEST_F(BlockerTest, TestBlockerMutuallyPrimeChunkandBlockSize) { | 124 TEST_F(BlockerTest, TestBlockerMutuallyPrimeChunkandBlockSize) { |
125 const int kNumInputChannels = 3; | 125 const size_t kNumInputChannels = 3; |
126 const int kNumOutputChannels = 2; | 126 const size_t kNumOutputChannels = 2; |
127 const size_t kNumFrames = 10; | 127 const size_t kNumFrames = 10; |
128 const size_t kBlockSize = 4; | 128 const size_t kBlockSize = 4; |
129 const size_t kChunkSize = 5; | 129 const size_t kChunkSize = 5; |
130 const size_t kShiftAmount = 2; | 130 const size_t kShiftAmount = 2; |
131 | 131 |
132 const float kInput[kNumInputChannels][kNumFrames] = { | 132 const float kInput[kNumInputChannels][kNumFrames] = { |
133 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, | 133 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, |
134 {2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, | 134 {2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, |
135 {3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}; | 135 {3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}; |
136 ChannelBuffer<float> input_cb(kNumFrames, kNumInputChannels); | 136 ChannelBuffer<float> input_cb(kNumFrames, kNumInputChannels); |
(...skipping 31 matching lines...) Loading... |
168 kNumInputChannels, | 168 kNumInputChannels, |
169 kNumOutputChannels); | 169 kNumOutputChannels); |
170 | 170 |
171 ValidateSignalEquality(expected_output_cb.channels(), | 171 ValidateSignalEquality(expected_output_cb.channels(), |
172 actual_output_cb.channels(), | 172 actual_output_cb.channels(), |
173 kNumOutputChannels, | 173 kNumOutputChannels, |
174 kNumFrames); | 174 kNumFrames); |
175 } | 175 } |
176 | 176 |
177 TEST_F(BlockerTest, TestBlockerMutuallyPrimeShiftAndBlockSize) { | 177 TEST_F(BlockerTest, TestBlockerMutuallyPrimeShiftAndBlockSize) { |
178 const int kNumInputChannels = 3; | 178 const size_t kNumInputChannels = 3; |
179 const int kNumOutputChannels = 2; | 179 const size_t kNumOutputChannels = 2; |
180 const size_t kNumFrames = 12; | 180 const size_t kNumFrames = 12; |
181 const size_t kBlockSize = 4; | 181 const size_t kBlockSize = 4; |
182 const size_t kChunkSize = 6; | 182 const size_t kChunkSize = 6; |
183 const size_t kShiftAmount = 3; | 183 const size_t kShiftAmount = 3; |
184 | 184 |
185 const float kInput[kNumInputChannels][kNumFrames] = { | 185 const float kInput[kNumInputChannels][kNumFrames] = { |
186 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, | 186 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, |
187 {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, | 187 {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, |
188 {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}; | 188 {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}; |
189 ChannelBuffer<float> input_cb(kNumFrames, kNumInputChannels); | 189 ChannelBuffer<float> input_cb(kNumFrames, kNumInputChannels); |
(...skipping 31 matching lines...) Loading... |
221 kNumInputChannels, | 221 kNumInputChannels, |
222 kNumOutputChannels); | 222 kNumOutputChannels); |
223 | 223 |
224 ValidateSignalEquality(expected_output_cb.channels(), | 224 ValidateSignalEquality(expected_output_cb.channels(), |
225 actual_output_cb.channels(), | 225 actual_output_cb.channels(), |
226 kNumOutputChannels, | 226 kNumOutputChannels, |
227 kNumFrames); | 227 kNumFrames); |
228 } | 228 } |
229 | 229 |
230 TEST_F(BlockerTest, TestBlockerNoOverlap) { | 230 TEST_F(BlockerTest, TestBlockerNoOverlap) { |
231 const int kNumInputChannels = 3; | 231 const size_t kNumInputChannels = 3; |
232 const int kNumOutputChannels = 2; | 232 const size_t kNumOutputChannels = 2; |
233 const size_t kNumFrames = 12; | 233 const size_t kNumFrames = 12; |
234 const size_t kBlockSize = 4; | 234 const size_t kBlockSize = 4; |
235 const size_t kChunkSize = 4; | 235 const size_t kChunkSize = 4; |
236 const size_t kShiftAmount = 4; | 236 const size_t kShiftAmount = 4; |
237 | 237 |
238 const float kInput[kNumInputChannels][kNumFrames] = { | 238 const float kInput[kNumInputChannels][kNumFrames] = { |
239 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, | 239 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, |
240 {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, | 240 {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, |
241 {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}; | 241 {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}; |
242 ChannelBuffer<float> input_cb(kNumFrames, kNumInputChannels); | 242 ChannelBuffer<float> input_cb(kNumFrames, kNumInputChannels); |
(...skipping 31 matching lines...) Loading... |
274 kNumInputChannels, | 274 kNumInputChannels, |
275 kNumOutputChannels); | 275 kNumOutputChannels); |
276 | 276 |
277 ValidateSignalEquality(expected_output_cb.channels(), | 277 ValidateSignalEquality(expected_output_cb.channels(), |
278 actual_output_cb.channels(), | 278 actual_output_cb.channels(), |
279 kNumOutputChannels, | 279 kNumOutputChannels, |
280 kNumFrames); | 280 kNumFrames); |
281 } | 281 } |
282 | 282 |
283 TEST_F(BlockerTest, InitialDelaysAreMinimum) { | 283 TEST_F(BlockerTest, InitialDelaysAreMinimum) { |
284 const int kNumInputChannels = 3; | 284 const size_t kNumInputChannels = 3; |
285 const int kNumOutputChannels = 2; | 285 const size_t kNumOutputChannels = 2; |
286 const size_t kNumFrames = 1280; | 286 const size_t kNumFrames = 1280; |
287 const size_t kChunkSize[] = | 287 const size_t kChunkSize[] = |
288 {80, 80, 80, 80, 80, 80, 160, 160, 160, 160, 160, 160}; | 288 {80, 80, 80, 80, 80, 80, 160, 160, 160, 160, 160, 160}; |
289 const size_t kBlockSize[] = | 289 const size_t kBlockSize[] = |
290 {64, 64, 64, 128, 128, 128, 128, 128, 128, 256, 256, 256}; | 290 {64, 64, 64, 128, 128, 128, 128, 128, 128, 256, 256, 256}; |
291 const size_t kShiftAmount[] = | 291 const size_t kShiftAmount[] = |
292 {16, 32, 64, 32, 64, 128, 32, 64, 128, 64, 128, 256}; | 292 {16, 32, 64, 32, 64, 128, 32, 64, 128, 64, 128, 256}; |
293 const size_t kInitialDelay[] = | 293 const size_t kInitialDelay[] = |
294 {48, 48, 48, 112, 112, 112, 96, 96, 96, 224, 224, 224}; | 294 {48, 48, 48, 112, 112, 112, 96, 96, 96, 224, 224, 224}; |
295 | 295 |
296 float input[kNumInputChannels][kNumFrames]; | 296 float input[kNumInputChannels][kNumFrames]; |
297 for (int i = 0; i < kNumInputChannels; ++i) { | 297 for (size_t i = 0; i < kNumInputChannels; ++i) { |
298 for (size_t j = 0; j < kNumFrames; ++j) { | 298 for (size_t j = 0; j < kNumFrames; ++j) { |
299 input[i][j] = i + 1; | 299 input[i][j] = i + 1; |
300 } | 300 } |
301 } | 301 } |
302 ChannelBuffer<float> input_cb(kNumFrames, kNumInputChannels); | 302 ChannelBuffer<float> input_cb(kNumFrames, kNumInputChannels); |
303 input_cb.SetDataForTesting(input[0], sizeof(input) / sizeof(**input)); | 303 input_cb.SetDataForTesting(input[0], sizeof(input) / sizeof(**input)); |
304 | 304 |
305 ChannelBuffer<float> output_cb(kNumFrames, kNumOutputChannels); | 305 ChannelBuffer<float> output_cb(kNumFrames, kNumOutputChannels); |
306 | 306 |
307 CopyBlockerCallback callback; | 307 CopyBlockerCallback callback; |
(...skipping 26 matching lines...) Loading... |
334 kNumOutputChannels); | 334 kNumOutputChannels); |
335 | 335 |
336 ValidateInitialDelay(output_cb.channels(), | 336 ValidateInitialDelay(output_cb.channels(), |
337 kNumOutputChannels, | 337 kNumOutputChannels, |
338 kNumFrames, | 338 kNumFrames, |
339 kInitialDelay[i]); | 339 kInitialDelay[i]); |
340 } | 340 } |
341 } | 341 } |
342 | 342 |
343 } // namespace webrtc | 343 } // namespace webrtc |
OLD | NEW |