Home | History | Annotate | Download | only in neteq
      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
    395