Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / audio_vector_unittest.cc
1 /*
2  *  Copyright (c) 2012 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
11 #include "webrtc/modules/audio_coding/neteq/audio_vector.h"
12
13 #include <assert.h>
14 #include <stdlib.h>
15
16 #include <string>
17
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "webrtc/typedefs.h"
20
21 namespace webrtc {
22
23 class AudioVectorTest : public ::testing::Test {
24  protected:
25   virtual void SetUp() {
26     // Populate test array.
27     for (size_t i = 0; i < array_length(); ++i) {
28       array_[i] = i;
29     }
30   }
31
32   size_t array_length() const {
33     return sizeof(array_) / sizeof(array_[0]);
34   }
35
36   int16_t array_[10];
37 };
38
39 // Create and destroy AudioVector objects, both empty and with a predefined
40 // length.
41 TEST_F(AudioVectorTest, CreateAndDestroy) {
42   AudioVector vec1;
43   EXPECT_TRUE(vec1.Empty());
44   EXPECT_EQ(0u, vec1.Size());
45
46   size_t initial_size = 17;
47   AudioVector vec2(initial_size);
48   EXPECT_FALSE(vec2.Empty());
49   EXPECT_EQ(initial_size, vec2.Size());
50 }
51
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);
59   }
60 }
61
62 // Test the PushBack method and the CopyFrom method. The Clear method is also
63 // invoked.
64 TEST_F(AudioVectorTest, PushBackAndCopy) {
65   AudioVector vec;
66   AudioVector vec_copy;
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]);
74   }
75
76   // Clear |vec| and verify that it is empty.
77   vec.Clear();
78   EXPECT_TRUE(vec.Empty());
79
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());
83 }
84
85 // Try to copy to a NULL pointer. Nothing should happen.
86 TEST_F(AudioVectorTest, CopyToNull) {
87   AudioVector vec;
88   AudioVector* vec_copy = NULL;
89   vec.PushBack(array_, array_length());
90   vec.CopyTo(vec_copy);
91 }
92
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);
103   }
104   // Append vec2 to the back of vec1.
105   vec1.PushBack(vec2);
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]);
109   }
110 }
111
112 // Test the PushFront method.
113 TEST_F(AudioVectorTest, PushFront) {
114   AudioVector vec;
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]);
119   }
120 }
121
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);
132   }
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]);
138   }
139 }
140
141 // Test the PopFront method.
142 TEST_F(AudioVectorTest, PopFront) {
143   AudioVector vec;
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]);
149   }
150   vec.PopFront(array_length());  // Remove more elements than vector size.
151   EXPECT_EQ(0u, vec.Size());
152 }
153
154 // Test the PopBack method.
155 TEST_F(AudioVectorTest, PopBack) {
156   AudioVector vec;
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]);
162   }
163   vec.PopBack(array_length());  // Remove more elements than vector size.
164   EXPECT_EQ(0u, vec.Size());
165 }
166
167 // Test the Extend method.
168 TEST_F(AudioVectorTest, Extend) {
169   AudioVector vec;
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]);
176   }
177 }
178
179 // Test the InsertAt method with an insert position in the middle of the vector.
180 TEST_F(AudioVectorTest, InsertAt) {
181   AudioVector vec;
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;
188   }
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}.
194   size_t pos = 0;
195   for (int i = 0; i < insert_position; ++i) {
196     EXPECT_EQ(array_[i], vec[pos]);
197     ++pos;
198   }
199   for (int i = 0; i < kNewLength; ++i) {
200     EXPECT_EQ(new_array[i], vec[pos]);
201     ++pos;
202   }
203   for (size_t i = insert_position; i < array_length(); ++i) {
204     EXPECT_EQ(array_[i], vec[pos]);
205     ++pos;
206   }
207 }
208
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) {
212   AudioVector vec;
213   AudioVector vec_ref;
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]);
225   }
226 }
227
228 // Test the InsertAt method with an insert position at the start of the vector.
229 TEST_F(AudioVectorTest, InsertAtBeginning) {
230   AudioVector vec;
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;
237   }
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}.
243   size_t pos = 0;
244   for (int i = 0; i < kNewLength; ++i) {
245     EXPECT_EQ(new_array[i], vec[pos]);
246     ++pos;
247   }
248   for (size_t i = insert_position; i < array_length(); ++i) {
249     EXPECT_EQ(array_[i], vec[pos]);
250     ++pos;
251   }
252 }
253
254 // Test the InsertAt method with an insert position at the end of the vector.
255 TEST_F(AudioVectorTest, InsertAtEnd) {
256   AudioVector vec;
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;
263   }
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 }.
268   size_t pos = 0;
269   for (size_t i = 0; i < array_length(); ++i) {
270     EXPECT_EQ(array_[i], vec[pos]);
271     ++pos;
272   }
273   for (int i = 0; i < kNewLength; ++i) {
274     EXPECT_EQ(new_array[i], vec[pos]);
275     ++pos;
276   }
277 }
278
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
283 // allowed value.
284 TEST_F(AudioVectorTest, InsertBeyondEnd) {
285   AudioVector vec;
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;
292   }
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 }.
297   size_t pos = 0;
298   for (size_t i = 0; i < array_length(); ++i) {
299     EXPECT_EQ(array_[i], vec[pos]);
300     ++pos;
301   }
302   for (int i = 0; i < kNewLength; ++i) {
303     EXPECT_EQ(new_array[i], vec[pos]);
304     ++pos;
305   }
306 }
307
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) {
311   AudioVector vec;
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;
318   }
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}.
324   size_t pos = 0;
325   for (pos = 0; pos < insert_position; ++pos) {
326     EXPECT_EQ(array_[pos], vec[pos]);
327   }
328   for (int i = 0; i < kNewLength; ++i) {
329     EXPECT_EQ(new_array[i], vec[pos]);
330     ++pos;
331   }
332   for (; pos < array_length(); ++pos) {
333     EXPECT_EQ(array_[pos], vec[pos]);
334   }
335 }
336
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) {
341   AudioVector vec;
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;
348   }
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}.
355   int pos = 0;
356   for (pos = 0; pos < insert_position; ++pos) {
357     EXPECT_EQ(array_[pos], vec[pos]);
358   }
359   for (int i = 0; i < kNewLength; ++i) {
360     EXPECT_EQ(new_array[i], vec[pos]);
361     ++pos;
362   }
363   // Verify that we checked to the end of |vec|.
364   EXPECT_EQ(vec.Size(), static_cast<size_t>(pos));
365 }
366
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) {
374     vec1[i] = 0;
375     vec2[i] = 100;
376   }
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]);
382   }
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);
387   }
388   // Second part untouched.
389   for (size_t i = kLength; i < vec1.Size(); ++i) {
390     EXPECT_EQ(100, vec1[i]);
391   }
392 }
393
394 }  // namespace webrtc