Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / audio_multi_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_multi_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 // This is a value-parameterized test. The test cases are instantiated with
24 // different values for the test parameter, which is used to determine the
25 // number of channels in the AudioMultiBuffer. Note that it is not possible
26 // to combine typed testing with value-parameterized testing, and since the
27 // tests for AudioVector already covers a number of different type parameters,
28 // this test focuses on testing different number of channels, and keeping the
29 // value type constant.
30
31 class AudioMultiVectorTest : public ::testing::TestWithParam<size_t> {
32  protected:
33   AudioMultiVectorTest()
34       : num_channels_(GetParam()),  // Get the test parameter.
35         interleaved_length_(num_channels_ * array_length()) {
36     array_interleaved_ = new int16_t[num_channels_ * array_length()];
37   }
38
39   ~AudioMultiVectorTest() {
40     delete [] array_interleaved_;
41   }
42
43   virtual void SetUp() {
44     // Populate test arrays.
45     for (size_t i = 0; i < array_length(); ++i) {
46       array_[i] = static_cast<int16_t>(i);
47     }
48     int16_t* ptr = array_interleaved_;
49     // Write 100, 101, 102, ... for first channel.
50     // Write 200, 201, 202, ... for second channel.
51     // And so on.
52     for (size_t i = 0; i < array_length(); ++i) {
53       for (size_t j = 1; j <= num_channels_; ++j) {
54         *ptr = j * 100 + i;
55         ++ptr;
56       }
57     }
58   }
59
60   size_t array_length() const {
61     return sizeof(array_) / sizeof(array_[0]);
62   }
63
64   const size_t num_channels_;
65   size_t interleaved_length_;
66   int16_t array_[10];
67   int16_t* array_interleaved_;
68 };
69
70 // Create and destroy AudioMultiVector objects, both empty and with a predefined
71 // length.
72 TEST_P(AudioMultiVectorTest, CreateAndDestroy) {
73   AudioMultiVector vec1(num_channels_);
74   EXPECT_TRUE(vec1.Empty());
75   EXPECT_EQ(num_channels_, vec1.Channels());
76   EXPECT_EQ(0u, vec1.Size());
77
78   size_t initial_size = 17;
79   AudioMultiVector vec2(num_channels_, initial_size);
80   EXPECT_FALSE(vec2.Empty());
81   EXPECT_EQ(num_channels_, vec2.Channels());
82   EXPECT_EQ(initial_size, vec2.Size());
83 }
84
85 // Test the subscript operator [] for getting and setting.
86 TEST_P(AudioMultiVectorTest, SubscriptOperator) {
87   AudioMultiVector vec(num_channels_, array_length());
88   for (size_t channel = 0; channel < num_channels_; ++channel) {
89     for (size_t i = 0; i < array_length(); ++i) {
90       vec[channel][i] = static_cast<int16_t>(i);
91       // Make sure to use the const version.
92       const AudioVector& audio_vec = vec[channel];
93       EXPECT_EQ(static_cast<int16_t>(i), audio_vec[i]);
94     }
95   }
96 }
97
98 // Test the PushBackInterleaved method and the CopyFrom method. The Clear
99 // method is also invoked.
100 TEST_P(AudioMultiVectorTest, PushBackInterleavedAndCopy) {
101   AudioMultiVector vec(num_channels_);
102   vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
103   AudioMultiVector vec_copy(num_channels_);
104   vec.CopyTo(&vec_copy);  // Copy from |vec| to |vec_copy|.
105   ASSERT_EQ(num_channels_, vec.Channels());
106   ASSERT_EQ(array_length(), vec.Size());
107   ASSERT_EQ(num_channels_, vec_copy.Channels());
108   ASSERT_EQ(array_length(), vec_copy.Size());
109   for (size_t channel = 0; channel < vec.Channels(); ++channel) {
110     for (size_t i = 0; i < array_length(); ++i) {
111       EXPECT_EQ(static_cast<int16_t>((channel + 1) * 100 + i), vec[channel][i]);
112       EXPECT_EQ(vec[channel][i], vec_copy[channel][i]);
113     }
114   }
115
116   // Clear |vec| and verify that it is empty.
117   vec.Clear();
118   EXPECT_TRUE(vec.Empty());
119
120   // Now copy the empty vector and verify that the copy becomes empty too.
121   vec.CopyTo(&vec_copy);
122   EXPECT_TRUE(vec_copy.Empty());
123 }
124
125 // Try to copy to a NULL pointer. Nothing should happen.
126 TEST_P(AudioMultiVectorTest, CopyToNull) {
127   AudioMultiVector vec(num_channels_);
128   AudioMultiVector* vec_copy = NULL;
129   vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
130   vec.CopyTo(vec_copy);
131 }
132
133 // Test the PushBack method with another AudioMultiVector as input argument.
134 TEST_P(AudioMultiVectorTest, PushBackVector) {
135   AudioMultiVector vec1(num_channels_, array_length());
136   AudioMultiVector vec2(num_channels_, array_length());
137   // Set the first vector to [0, 1, ..., array_length() - 1] +
138   //   100 * channel_number.
139   // Set the second vector to [array_length(), array_length() + 1, ...,
140   //   2 * array_length() - 1] + 100 * channel_number.
141   for (size_t channel = 0; channel < num_channels_; ++channel) {
142     for (size_t i = 0; i < array_length(); ++i) {
143       vec1[channel][i] = static_cast<int16_t>(i + 100 * channel);
144       vec2[channel][i] =
145           static_cast<int16_t>(i + 100 * channel + array_length());
146     }
147   }
148   // Append vec2 to the back of vec1.
149   vec1.PushBack(vec2);
150   ASSERT_EQ(2u * array_length(), vec1.Size());
151   for (size_t channel = 0; channel < num_channels_; ++channel) {
152     for (size_t i = 0; i < 2 * array_length(); ++i) {
153       EXPECT_EQ(static_cast<int16_t>(i + 100 * channel), vec1[channel][i]);
154     }
155   }
156 }
157
158 // Test the PushBackFromIndex method.
159 TEST_P(AudioMultiVectorTest, PushBackFromIndex) {
160   AudioMultiVector vec1(num_channels_);
161   vec1.PushBackInterleaved(array_interleaved_, interleaved_length_);
162   AudioMultiVector vec2(num_channels_);
163
164   // Append vec1 to the back of vec2 (which is empty). Read vec1 from the second
165   // last element.
166   vec2.PushBackFromIndex(vec1, array_length() - 2);
167   ASSERT_EQ(2u, vec2.Size());
168   for (size_t channel = 0; channel < num_channels_; ++channel) {
169     for (size_t i = 0; i < 2; ++i) {
170       EXPECT_EQ(array_interleaved_[channel + num_channels_ *
171                   (array_length() - 2 + i)], vec2[channel][i]);
172     }
173   }
174 }
175
176 // Starts with pushing some values to the vector, then test the Zeros method.
177 TEST_P(AudioMultiVectorTest, Zeros) {
178   AudioMultiVector vec(num_channels_);
179   vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
180   vec.Zeros(2 * array_length());
181   ASSERT_EQ(num_channels_, vec.Channels());
182   ASSERT_EQ(2u * array_length(), vec.Size());
183   for (size_t channel = 0; channel < num_channels_; ++channel) {
184     for (size_t i = 0; i < 2 * array_length(); ++i) {
185       EXPECT_EQ(0, vec[channel][i]);
186     }
187   }
188 }
189
190 // Test the ReadInterleaved method
191 TEST_P(AudioMultiVectorTest, ReadInterleaved) {
192   AudioMultiVector vec(num_channels_);
193   vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
194   int16_t* output = new int16_t[interleaved_length_];
195   // Read 5 samples.
196   size_t read_samples = 5;
197   EXPECT_EQ(num_channels_ * read_samples,
198             vec.ReadInterleaved(read_samples, output));
199   EXPECT_EQ(0,
200             memcmp(array_interleaved_, output, read_samples * sizeof(int16_t)));
201
202   // Read too many samples. Expect to get all samples from the vector.
203   EXPECT_EQ(interleaved_length_,
204             vec.ReadInterleaved(array_length() + 1, output));
205   EXPECT_EQ(0,
206             memcmp(array_interleaved_, output, read_samples * sizeof(int16_t)));
207
208   delete [] output;
209 }
210
211 // Try to read to a NULL pointer. Expected to return 0.
212 TEST_P(AudioMultiVectorTest, ReadInterleavedToNull) {
213   AudioMultiVector vec(num_channels_);
214   vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
215   int16_t* output = NULL;
216   // Read 5 samples.
217   size_t read_samples = 5;
218   EXPECT_EQ(0u, vec.ReadInterleaved(read_samples, output));
219 }
220
221 // Test the PopFront method.
222 TEST_P(AudioMultiVectorTest, PopFront) {
223   AudioMultiVector vec(num_channels_);
224   vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
225   vec.PopFront(1);  // Remove one element from each channel.
226   ASSERT_EQ(array_length() - 1u, vec.Size());
227   // Let |ptr| point to the second element of the first channel in the
228   // interleaved array.
229   int16_t* ptr = &array_interleaved_[num_channels_];
230   for (size_t i = 0; i < array_length() - 1; ++i) {
231     for (size_t channel = 0; channel < num_channels_; ++channel) {
232       EXPECT_EQ(*ptr, vec[channel][i]);
233       ++ptr;
234     }
235   }
236   vec.PopFront(array_length());  // Remove more elements than vector size.
237   EXPECT_EQ(0u, vec.Size());
238 }
239
240 // Test the PopBack method.
241 TEST_P(AudioMultiVectorTest, PopBack) {
242   AudioMultiVector vec(num_channels_);
243   vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
244   vec.PopBack(1);  // Remove one element from each channel.
245   ASSERT_EQ(array_length() - 1u, vec.Size());
246   // Let |ptr| point to the first element of the first channel in the
247   // interleaved array.
248   int16_t* ptr = array_interleaved_;
249   for (size_t i = 0; i < array_length() - 1; ++i) {
250     for (size_t channel = 0; channel < num_channels_; ++channel) {
251       EXPECT_EQ(*ptr, vec[channel][i]);
252       ++ptr;
253     }
254   }
255   vec.PopBack(array_length());  // Remove more elements than vector size.
256   EXPECT_EQ(0u, vec.Size());
257 }
258
259 // Test the AssertSize method.
260 TEST_P(AudioMultiVectorTest, AssertSize) {
261   AudioMultiVector vec(num_channels_, array_length());
262   EXPECT_EQ(array_length(), vec.Size());
263   // Start with asserting with smaller sizes than already allocated.
264   vec.AssertSize(0);
265   vec.AssertSize(array_length() - 1);
266   // Nothing should have changed.
267   EXPECT_EQ(array_length(), vec.Size());
268   // Assert with one element longer than already allocated.
269   vec.AssertSize(array_length() + 1);
270   // Expect vector to have grown.
271   EXPECT_EQ(array_length() + 1, vec.Size());
272   // Also check the individual AudioVectors.
273   for (size_t channel = 0; channel < vec.Channels(); ++channel) {
274     EXPECT_EQ(array_length() + 1u, vec[channel].Size());
275   }
276 }
277
278 // Test the PushBack method with another AudioMultiVector as input argument.
279 TEST_P(AudioMultiVectorTest, OverwriteAt) {
280   AudioMultiVector vec1(num_channels_);
281   vec1.PushBackInterleaved(array_interleaved_, interleaved_length_);
282   AudioMultiVector vec2(num_channels_);
283   vec2.Zeros(3);  // 3 zeros in each channel.
284   // Overwrite vec2 at position 5.
285   vec1.OverwriteAt(vec2, 3, 5);
286   // Verify result.
287   // Length remains the same.
288   ASSERT_EQ(array_length(), vec1.Size());
289   int16_t* ptr = array_interleaved_;
290   for (size_t i = 0; i < array_length() - 1; ++i) {
291     for (size_t channel = 0; channel < num_channels_; ++channel) {
292       if (i >= 5 && i <= 7) {
293         // Elements 5, 6, 7 should have been replaced with zeros.
294         EXPECT_EQ(0, vec1[channel][i]);
295       } else {
296         EXPECT_EQ(*ptr, vec1[channel][i]);
297       }
298       ++ptr;
299     }
300   }
301 }
302
303 // Test the CopyChannel method, when the test is instantiated with at least two
304 // channels.
305 TEST_P(AudioMultiVectorTest, CopyChannel) {
306   if (num_channels_ < 2)
307     return;
308
309   AudioMultiVector vec(num_channels_);
310   vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
311   // Create a reference copy.
312   AudioMultiVector ref(num_channels_);
313   ref.PushBack(vec);
314   // Copy from first to last channel.
315   vec.CopyChannel(0, num_channels_ - 1);
316   // Verify that the first and last channels are identical; the others should
317   // be left untouched.
318   for (size_t i = 0; i < array_length(); ++i) {
319     // Verify that all but the last channel are untouched.
320     for (size_t channel = 0; channel < num_channels_ - 1; ++channel) {
321       EXPECT_EQ(ref[channel][i], vec[channel][i]);
322     }
323     // Verify that the last and the first channels are identical.
324     EXPECT_EQ(vec[0][i], vec[num_channels_ - 1][i]);
325   }
326 }
327
328 INSTANTIATE_TEST_CASE_P(TestNumChannels,
329                         AudioMultiVectorTest,
330                         ::testing::Values(static_cast<size_t>(1),
331                                           static_cast<size_t>(2),
332                                           static_cast<size_t>(5)));
333 }  // namespace webrtc