2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/audio_coding/neteq/audio_vector.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "webrtc/typedefs.h"
23 class AudioVectorTest : public ::testing::Test {
25 virtual void SetUp() {
26 // Populate test array.
27 for (size_t i = 0; i < array_length(); ++i) {
32 size_t array_length() const {
33 return sizeof(array_) / sizeof(array_[0]);
39 // Create and destroy AudioVector objects, both empty and with a predefined
41 TEST_F(AudioVectorTest, CreateAndDestroy) {
43 EXPECT_TRUE(vec1.Empty());
44 EXPECT_EQ(0u, vec1.Size());
46 size_t initial_size = 17;
47 AudioVector vec2(initial_size);
48 EXPECT_FALSE(vec2.Empty());
49 EXPECT_EQ(initial_size, vec2.Size());
52 // Test the subscript operator [] for getting and setting.
53 TEST_F(AudioVectorTest, SubscriptOperator) {
54 AudioVector vec(array_length());
55 for (size_t i = 0; i < array_length(); ++i) {
56 vec[i] = static_cast<int16_t>(i);
57 const int16_t& value = vec[i]; // Make sure to use the const version.
58 EXPECT_EQ(static_cast<int16_t>(i), value);
62 // Test the PushBack method and the CopyFrom method. The Clear method is also
64 TEST_F(AudioVectorTest, PushBackAndCopy) {
67 vec.PushBack(array_, array_length());
68 vec.CopyTo(&vec_copy); // Copy from |vec| to |vec_copy|.
69 ASSERT_EQ(array_length(), vec.Size());
70 ASSERT_EQ(array_length(), vec_copy.Size());
71 for (size_t i = 0; i < array_length(); ++i) {
72 EXPECT_EQ(array_[i], vec[i]);
73 EXPECT_EQ(array_[i], vec_copy[i]);
76 // Clear |vec| and verify that it is empty.
78 EXPECT_TRUE(vec.Empty());
80 // Now copy the empty vector and verify that the copy becomes empty too.
81 vec.CopyTo(&vec_copy);
82 EXPECT_TRUE(vec_copy.Empty());
85 // Try to copy to a NULL pointer. Nothing should happen.
86 TEST_F(AudioVectorTest, CopyToNull) {
88 AudioVector* vec_copy = NULL;
89 vec.PushBack(array_, array_length());
93 // Test the PushBack method with another AudioVector as input argument.
94 TEST_F(AudioVectorTest, PushBackVector) {
95 static const size_t kLength = 10;
96 AudioVector vec1(kLength);
97 AudioVector vec2(kLength);
98 // Set the first vector to [0, 1, ..., kLength - 1].
99 // Set the second vector to [kLength, kLength + 1, ..., 2 * kLength - 1].
100 for (size_t i = 0; i < kLength; ++i) {
101 vec1[i] = static_cast<int16_t>(i);
102 vec2[i] = static_cast<int16_t>(i + kLength);
104 // Append vec2 to the back of vec1.
106 ASSERT_EQ(2 * kLength, vec1.Size());
107 for (size_t i = 0; i < 2 * kLength; ++i) {
108 EXPECT_EQ(static_cast<int16_t>(i), vec1[i]);
112 // Test the PushFront method.
113 TEST_F(AudioVectorTest, PushFront) {
115 vec.PushFront(array_, array_length());
116 ASSERT_EQ(array_length(), vec.Size());
117 for (size_t i = 0; i < array_length(); ++i) {
118 EXPECT_EQ(array_[i], vec[i]);
122 // Test the PushFront method with another AudioVector as input argument.
123 TEST_F(AudioVectorTest, PushFrontVector) {
124 static const size_t kLength = 10;
125 AudioVector vec1(kLength);
126 AudioVector vec2(kLength);
127 // Set the first vector to [0, 1, ..., kLength - 1].
128 // Set the second vector to [kLength, kLength + 1, ..., 2 * kLength - 1].
129 for (size_t i = 0; i < kLength; ++i) {
130 vec1[i] = static_cast<int16_t>(i);
131 vec2[i] = static_cast<int16_t>(i + kLength);
133 // Prepend vec1 to the front of vec2.
134 vec2.PushFront(vec1);
135 ASSERT_EQ(2 * kLength, vec2.Size());
136 for (size_t i = 0; i < 2 * kLength; ++i) {
137 EXPECT_EQ(static_cast<int16_t>(i), vec2[i]);
141 // Test the PopFront method.
142 TEST_F(AudioVectorTest, PopFront) {
144 vec.PushBack(array_, array_length());
145 vec.PopFront(1); // Remove one element.
146 EXPECT_EQ(array_length() - 1u, vec.Size());
147 for (size_t i = 0; i < array_length() - 1; ++i) {
148 EXPECT_EQ(static_cast<int16_t>(i + 1), vec[i]);
150 vec.PopFront(array_length()); // Remove more elements than vector size.
151 EXPECT_EQ(0u, vec.Size());
154 // Test the PopBack method.
155 TEST_F(AudioVectorTest, PopBack) {
157 vec.PushBack(array_, array_length());
158 vec.PopBack(1); // Remove one element.
159 EXPECT_EQ(array_length() - 1u, vec.Size());
160 for (size_t i = 0; i < array_length() - 1; ++i) {
161 EXPECT_EQ(static_cast<int16_t>(i), vec[i]);
163 vec.PopBack(array_length()); // Remove more elements than vector size.
164 EXPECT_EQ(0u, vec.Size());
167 // Test the Extend method.
168 TEST_F(AudioVectorTest, Extend) {
170 vec.PushBack(array_, array_length());
171 vec.Extend(5); // Extend with 5 elements, which should all be zeros.
172 ASSERT_EQ(array_length() + 5u, vec.Size());
173 // Verify that all are zero.
174 for (size_t i = array_length(); i < array_length() + 5; ++i) {
175 EXPECT_EQ(0, vec[i]);
179 // Test the InsertAt method with an insert position in the middle of the vector.
180 TEST_F(AudioVectorTest, InsertAt) {
182 vec.PushBack(array_, array_length());
183 static const int kNewLength = 5;
184 int16_t new_array[kNewLength];
185 // Set array elements to {100, 101, 102, ... }.
186 for (int i = 0; i < kNewLength; ++i) {
187 new_array[i] = 100 + i;
189 int insert_position = 5;
190 vec.InsertAt(new_array, kNewLength, insert_position);
191 // Verify that the vector looks as follows:
192 // {0, 1, ..., |insert_position| - 1, 100, 101, ..., 100 + kNewLength - 1,
193 // |insert_position|, |insert_position| + 1, ..., kLength - 1}.
195 for (int i = 0; i < insert_position; ++i) {
196 EXPECT_EQ(array_[i], vec[pos]);
199 for (int i = 0; i < kNewLength; ++i) {
200 EXPECT_EQ(new_array[i], vec[pos]);
203 for (size_t i = insert_position; i < array_length(); ++i) {
204 EXPECT_EQ(array_[i], vec[pos]);
209 // Test the InsertZerosAt method with an insert position in the middle of the
210 // vector. Use the InsertAt method as reference.
211 TEST_F(AudioVectorTest, InsertZerosAt) {
214 vec.PushBack(array_, array_length());
215 vec_ref.PushBack(array_, array_length());
216 static const int kNewLength = 5;
217 int insert_position = 5;
218 vec.InsertZerosAt(kNewLength, insert_position);
219 int16_t new_array[kNewLength] = {0}; // All zero elements.
220 vec_ref.InsertAt(new_array, kNewLength, insert_position);
221 // Verify that the vectors are identical.
222 ASSERT_EQ(vec_ref.Size(), vec.Size());
223 for (size_t i = 0; i < vec.Size(); ++i) {
224 EXPECT_EQ(vec_ref[i], vec[i]);
228 // Test the InsertAt method with an insert position at the start of the vector.
229 TEST_F(AudioVectorTest, InsertAtBeginning) {
231 vec.PushBack(array_, array_length());
232 static const int kNewLength = 5;
233 int16_t new_array[kNewLength];
234 // Set array elements to {100, 101, 102, ... }.
235 for (int i = 0; i < kNewLength; ++i) {
236 new_array[i] = 100 + i;
238 int insert_position = 0;
239 vec.InsertAt(new_array, kNewLength, insert_position);
240 // Verify that the vector looks as follows:
241 // {100, 101, ..., 100 + kNewLength - 1,
242 // 0, 1, ..., kLength - 1}.
244 for (int i = 0; i < kNewLength; ++i) {
245 EXPECT_EQ(new_array[i], vec[pos]);
248 for (size_t i = insert_position; i < array_length(); ++i) {
249 EXPECT_EQ(array_[i], vec[pos]);
254 // Test the InsertAt method with an insert position at the end of the vector.
255 TEST_F(AudioVectorTest, InsertAtEnd) {
257 vec.PushBack(array_, array_length());
258 static const int kNewLength = 5;
259 int16_t new_array[kNewLength];
260 // Set array elements to {100, 101, 102, ... }.
261 for (int i = 0; i < kNewLength; ++i) {
262 new_array[i] = 100 + i;
264 int insert_position = array_length();
265 vec.InsertAt(new_array, kNewLength, insert_position);
266 // Verify that the vector looks as follows:
267 // {0, 1, ..., kLength - 1, 100, 101, ..., 100 + kNewLength - 1 }.
269 for (size_t i = 0; i < array_length(); ++i) {
270 EXPECT_EQ(array_[i], vec[pos]);
273 for (int i = 0; i < kNewLength; ++i) {
274 EXPECT_EQ(new_array[i], vec[pos]);
279 // Test the InsertAt method with an insert position beyond the end of the
280 // vector. Verify that a position beyond the end of the vector does not lead to
281 // an error. The expected outcome is the same as if the vector end was used as
282 // input position. That is, the input position should be capped at the maximum
284 TEST_F(AudioVectorTest, InsertBeyondEnd) {
286 vec.PushBack(array_, array_length());
287 static const int kNewLength = 5;
288 int16_t new_array[kNewLength];
289 // Set array elements to {100, 101, 102, ... }.
290 for (int i = 0; i < kNewLength; ++i) {
291 new_array[i] = 100 + i;
293 int insert_position = array_length() + 10; // Too large.
294 vec.InsertAt(new_array, kNewLength, insert_position);
295 // Verify that the vector looks as follows:
296 // {0, 1, ..., kLength - 1, 100, 101, ..., 100 + kNewLength - 1 }.
298 for (size_t i = 0; i < array_length(); ++i) {
299 EXPECT_EQ(array_[i], vec[pos]);
302 for (int i = 0; i < kNewLength; ++i) {
303 EXPECT_EQ(new_array[i], vec[pos]);
308 // Test the OverwriteAt method with a position such that all of the new values
309 // fit within the old vector.
310 TEST_F(AudioVectorTest, OverwriteAt) {
312 vec.PushBack(array_, array_length());
313 static const int kNewLength = 5;
314 int16_t new_array[kNewLength];
315 // Set array elements to {100, 101, 102, ... }.
316 for (int i = 0; i < kNewLength; ++i) {
317 new_array[i] = 100 + i;
319 size_t insert_position = 2;
320 vec.OverwriteAt(new_array, kNewLength, insert_position);
321 // Verify that the vector looks as follows:
322 // {0, ..., |insert_position| - 1, 100, 101, ..., 100 + kNewLength - 1,
323 // |insert_position|, |insert_position| + 1, ..., kLength - 1}.
325 for (pos = 0; pos < insert_position; ++pos) {
326 EXPECT_EQ(array_[pos], vec[pos]);
328 for (int i = 0; i < kNewLength; ++i) {
329 EXPECT_EQ(new_array[i], vec[pos]);
332 for (; pos < array_length(); ++pos) {
333 EXPECT_EQ(array_[pos], vec[pos]);
337 // Test the OverwriteAt method with a position such that some of the new values
338 // extend beyond the end of the current vector. This is valid, and the vector is
339 // expected to expand to accommodate the new values.
340 TEST_F(AudioVectorTest, OverwriteBeyondEnd) {
342 vec.PushBack(array_, array_length());
343 static const int kNewLength = 5;
344 int16_t new_array[kNewLength];
345 // Set array elements to {100, 101, 102, ... }.
346 for (int i = 0; i < kNewLength; ++i) {
347 new_array[i] = 100 + i;
349 int insert_position = array_length() - 2;
350 vec.OverwriteAt(new_array, kNewLength, insert_position);
351 ASSERT_EQ(array_length() - 2u + kNewLength, vec.Size());
352 // Verify that the vector looks as follows:
353 // {0, ..., |insert_position| - 1, 100, 101, ..., 100 + kNewLength - 1,
354 // |insert_position|, |insert_position| + 1, ..., kLength - 1}.
356 for (pos = 0; pos < insert_position; ++pos) {
357 EXPECT_EQ(array_[pos], vec[pos]);
359 for (int i = 0; i < kNewLength; ++i) {
360 EXPECT_EQ(new_array[i], vec[pos]);
363 // Verify that we checked to the end of |vec|.
364 EXPECT_EQ(vec.Size(), static_cast<size_t>(pos));
367 TEST_F(AudioVectorTest, CrossFade) {
368 static const size_t kLength = 100;
369 static const size_t kFadeLength = 10;
370 AudioVector vec1(kLength);
371 AudioVector vec2(kLength);
372 // Set all vector elements to 0 in |vec1| and 100 in |vec2|.
373 for (size_t i = 0; i < kLength; ++i) {
377 vec1.CrossFade(vec2, kFadeLength);
378 ASSERT_EQ(2 * kLength - kFadeLength, vec1.Size());
379 // First part untouched.
380 for (size_t i = 0; i < kLength - kFadeLength; ++i) {
381 EXPECT_EQ(0, vec1[i]);
383 // Check mixing zone.
384 for (size_t i = 0 ; i < kFadeLength; ++i) {
385 EXPECT_NEAR((i + 1) * 100 / (kFadeLength + 1),
386 vec1[kLength - kFadeLength + i], 1);
388 // Second part untouched.
389 for (size_t i = kLength; i < vec1.Size(); ++i) {
390 EXPECT_EQ(100, vec1[i]);
394 } // namespace webrtc