Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: webrtc/webrtc/modules/audio_coding/neteq4/audio_multi_vector_unittest.cc @ 0:4bda6873e34c

pub_scrub_3792 tip
Last change on this file since 0:4bda6873e34c was 0:4bda6873e34c, checked in by Michael Prittie <mprittie@…>, 6 years ago

Scrubbed password for publication.

File size: 10.9 KB
Line 
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/neteq4/audio_multi_vector.h"
12
13#include <assert.h>
14#include <stdlib.h>
15
16#include <string>
17
18#include "gtest/gtest.h"
19#include "webrtc/typedefs.h"
20
21namespace 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
31class 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.
72TEST_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.
86TEST_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.
100TEST_P(AudioMultiVectorTest, PushBackInterleavedAndCopy) {
101  AudioMultiVector vec(num_channels_);
102  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
103  AudioMultiVector vec_copy(num_channels_);
104  vec.CopyFrom(&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.CopyFrom(&vec_copy);
122  EXPECT_TRUE(vec_copy.Empty());
123}
124
125// Try to copy to a NULL pointer. Nothing should happen.
126TEST_P(AudioMultiVectorTest, CopyToNull) {
127  AudioMultiVector vec(num_channels_);
128  AudioMultiVector* vec_copy = NULL;
129  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
130  vec.CopyFrom(vec_copy);
131}
132
133// Test the PushBack method with another AudioMultiVector as input argument.
134TEST_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.
159TEST_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.
177TEST_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
191TEST_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.
212TEST_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.
222TEST_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.
241TEST_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.
260TEST_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.
279TEST_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
303INSTANTIATE_TEST_CASE_P(TestNumChannels,
304                        AudioMultiVectorTest,
305                        ::testing::Values(static_cast<size_t>(1),
306                                          static_cast<size_t>(2),
307                                          static_cast<size_t>(5)));
308}  // namespace webrtc
Note: See TracBrowser for help on using the repository browser.