tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

audio_vector_unittest.cc (13496B)


      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 "modules/audio_coding/neteq/audio_vector.h"
     12 
     13 #include <array>
     14 #include <cstdint>
     15 #include <cstdlib>
     16 
     17 #include "api/audio/audio_view.h"
     18 #include "rtc_base/numerics/safe_conversions.h"
     19 #include "test/gtest.h"
     20 
     21 namespace webrtc {
     22 
     23 class AudioVectorTest : public ::testing::Test {
     24 protected:
     25  void SetUp() override {
     26    // Populate test array.
     27    for (size_t i = 0; i < array_length(); ++i) {
     28      array_[i] = checked_cast<int16_t>(i);
     29    }
     30  }
     31 
     32  constexpr 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 TEST_F(AudioVectorTest, CopyTo) {
     86  AudioVector vec;
     87  vec.PushBack(array_, array_length());
     88  ASSERT_EQ(vec.Size(), 10u);
     89 
     90  std::array<int16_t, 10> buffer;
     91  MonoView<int16_t> view(&buffer[0], buffer.size());
     92  // Try to read 10 samples from position 1, which should fail.
     93  EXPECT_FALSE(vec.CopyTo(1, view));
     94  // Reading 10 samples from position 0, should succeed.
     95  EXPECT_TRUE(vec.CopyTo(0, view));
     96  EXPECT_EQ(view[5], 5);  // sanity check.
     97 
     98  // Free up space at the front of the buffer. This changes
     99  // the internal start position without reallocating memory.
    100  vec.PopFront(2);
    101 
    102  std::array<int16_t, 2> new_values = {20, 21};
    103  vec.PushBack(&new_values[0], new_values.size());
    104 
    105  // Now the CopyTo() operation will need to wrap around
    106  // the end of the internal buffer to fill the view.
    107  EXPECT_TRUE(vec.CopyTo(0, view));
    108  EXPECT_EQ(view[0], 2);
    109  EXPECT_EQ(view[8], 20);
    110  EXPECT_EQ(view[9], 21);
    111 }
    112 
    113 // Test the PushBack method with another AudioVector as input argument.
    114 TEST_F(AudioVectorTest, PushBackVector) {
    115  static const size_t kLength = 10;
    116  AudioVector vec1(kLength);
    117  AudioVector vec2(kLength);
    118  // Set the first vector to [0, 1, ..., kLength - 1].
    119  // Set the second vector to [kLength, kLength + 1, ..., 2 * kLength - 1].
    120  for (size_t i = 0; i < kLength; ++i) {
    121    vec1[i] = static_cast<int16_t>(i);
    122    vec2[i] = static_cast<int16_t>(i + kLength);
    123  }
    124  // Append vec2 to the back of vec1.
    125  vec1.PushBack(vec2);
    126  ASSERT_EQ(2 * kLength, vec1.Size());
    127  for (size_t i = 0; i < 2 * kLength; ++i) {
    128    EXPECT_EQ(static_cast<int16_t>(i), vec1[i]);
    129  }
    130 }
    131 
    132 // Test the PushFront method.
    133 TEST_F(AudioVectorTest, PushFront) {
    134  AudioVector vec;
    135  vec.PushFront(array_, array_length());
    136  ASSERT_EQ(array_length(), vec.Size());
    137  for (size_t i = 0; i < array_length(); ++i) {
    138    EXPECT_EQ(array_[i], vec[i]);
    139  }
    140 }
    141 
    142 // Test the PushFront method with another AudioVector as input argument.
    143 TEST_F(AudioVectorTest, PushFrontVector) {
    144  static const size_t kLength = 10;
    145  AudioVector vec1(kLength);
    146  AudioVector vec2(kLength);
    147  // Set the first vector to [0, 1, ..., kLength - 1].
    148  // Set the second vector to [kLength, kLength + 1, ..., 2 * kLength - 1].
    149  for (size_t i = 0; i < kLength; ++i) {
    150    vec1[i] = static_cast<int16_t>(i);
    151    vec2[i] = static_cast<int16_t>(i + kLength);
    152  }
    153  // Prepend vec1 to the front of vec2.
    154  vec2.PushFront(vec1);
    155  ASSERT_EQ(2 * kLength, vec2.Size());
    156  for (size_t i = 0; i < 2 * kLength; ++i) {
    157    EXPECT_EQ(static_cast<int16_t>(i), vec2[i]);
    158  }
    159 }
    160 
    161 // Test the PopFront method.
    162 TEST_F(AudioVectorTest, PopFront) {
    163  AudioVector vec;
    164  vec.PushBack(array_, array_length());
    165  vec.PopFront(1);  // Remove one element.
    166  EXPECT_EQ(array_length() - 1u, vec.Size());
    167  for (size_t i = 0; i < array_length() - 1; ++i) {
    168    EXPECT_EQ(static_cast<int16_t>(i + 1), vec[i]);
    169  }
    170  vec.PopFront(array_length());  // Remove more elements than vector size.
    171  EXPECT_EQ(0u, vec.Size());
    172 }
    173 
    174 // Test the PopBack method.
    175 TEST_F(AudioVectorTest, PopBack) {
    176  AudioVector vec;
    177  vec.PushBack(array_, array_length());
    178  vec.PopBack(1);  // Remove one element.
    179  EXPECT_EQ(array_length() - 1u, vec.Size());
    180  for (size_t i = 0; i < array_length() - 1; ++i) {
    181    EXPECT_EQ(static_cast<int16_t>(i), vec[i]);
    182  }
    183  vec.PopBack(array_length());  // Remove more elements than vector size.
    184  EXPECT_EQ(0u, vec.Size());
    185 }
    186 
    187 // Test the Extend method.
    188 TEST_F(AudioVectorTest, Extend) {
    189  AudioVector vec;
    190  vec.PushBack(array_, array_length());
    191  vec.Extend(5);  // Extend with 5 elements, which should all be zeros.
    192  ASSERT_EQ(array_length() + 5u, vec.Size());
    193  // Verify that all are zero.
    194  for (size_t i = array_length(); i < array_length() + 5; ++i) {
    195    EXPECT_EQ(0, vec[i]);
    196  }
    197 }
    198 
    199 // Test the InsertAt method with an insert position in the middle of the vector.
    200 TEST_F(AudioVectorTest, InsertAt) {
    201  AudioVector vec;
    202  vec.PushBack(array_, array_length());
    203  static const int kNewLength = 5;
    204  int16_t new_array[kNewLength];
    205  // Set array elements to {100, 101, 102, ... }.
    206  for (int i = 0; i < kNewLength; ++i) {
    207    new_array[i] = 100 + i;
    208  }
    209  int insert_position = 5;
    210  vec.InsertAt(new_array, kNewLength, insert_position);
    211  // Verify that the vector looks as follows:
    212  // {0, 1, ..., `insert_position` - 1, 100, 101, ..., 100 + kNewLength - 1,
    213  //  `insert_position`, `insert_position` + 1, ..., kLength - 1}.
    214  size_t pos = 0;
    215  for (int i = 0; i < insert_position; ++i) {
    216    EXPECT_EQ(array_[i], vec[pos]);
    217    ++pos;
    218  }
    219  for (int i = 0; i < kNewLength; ++i) {
    220    EXPECT_EQ(new_array[i], vec[pos]);
    221    ++pos;
    222  }
    223  for (size_t i = insert_position; i < array_length(); ++i) {
    224    EXPECT_EQ(array_[i], vec[pos]);
    225    ++pos;
    226  }
    227 }
    228 
    229 // Test the InsertZerosAt method with an insert position in the middle of the
    230 // vector. Use the InsertAt method as reference.
    231 TEST_F(AudioVectorTest, InsertZerosAt) {
    232  AudioVector vec;
    233  AudioVector vec_ref;
    234  vec.PushBack(array_, array_length());
    235  vec_ref.PushBack(array_, array_length());
    236  static const int kNewLength = 5;
    237  int insert_position = 5;
    238  vec.InsertZerosAt(kNewLength, insert_position);
    239  int16_t new_array[kNewLength] = {0};  // All zero elements.
    240  vec_ref.InsertAt(new_array, kNewLength, insert_position);
    241  // Verify that the vectors are identical.
    242  ASSERT_EQ(vec_ref.Size(), vec.Size());
    243  for (size_t i = 0; i < vec.Size(); ++i) {
    244    EXPECT_EQ(vec_ref[i], vec[i]);
    245  }
    246 }
    247 
    248 // Test the InsertAt method with an insert position at the start of the vector.
    249 TEST_F(AudioVectorTest, InsertAtBeginning) {
    250  AudioVector vec;
    251  vec.PushBack(array_, array_length());
    252  static const int kNewLength = 5;
    253  int16_t new_array[kNewLength];
    254  // Set array elements to {100, 101, 102, ... }.
    255  for (int i = 0; i < kNewLength; ++i) {
    256    new_array[i] = 100 + i;
    257  }
    258  int insert_position = 0;
    259  vec.InsertAt(new_array, kNewLength, insert_position);
    260  // Verify that the vector looks as follows:
    261  // {100, 101, ..., 100 + kNewLength - 1,
    262  //  0, 1, ..., kLength - 1}.
    263  size_t pos = 0;
    264  for (int i = 0; i < kNewLength; ++i) {
    265    EXPECT_EQ(new_array[i], vec[pos]);
    266    ++pos;
    267  }
    268  for (size_t i = insert_position; i < array_length(); ++i) {
    269    EXPECT_EQ(array_[i], vec[pos]);
    270    ++pos;
    271  }
    272 }
    273 
    274 // Test the InsertAt method with an insert position at the end of the vector.
    275 TEST_F(AudioVectorTest, InsertAtEnd) {
    276  AudioVector vec;
    277  vec.PushBack(array_, array_length());
    278  static const int kNewLength = 5;
    279  int16_t new_array[kNewLength];
    280  // Set array elements to {100, 101, 102, ... }.
    281  for (int i = 0; i < kNewLength; ++i) {
    282    new_array[i] = 100 + i;
    283  }
    284  int insert_position = checked_cast<int>(array_length());
    285  vec.InsertAt(new_array, kNewLength, insert_position);
    286  // Verify that the vector looks as follows:
    287  // {0, 1, ..., kLength - 1, 100, 101, ..., 100 + kNewLength - 1 }.
    288  size_t pos = 0;
    289  for (size_t i = 0; i < array_length(); ++i) {
    290    EXPECT_EQ(array_[i], vec[pos]);
    291    ++pos;
    292  }
    293  for (int i = 0; i < kNewLength; ++i) {
    294    EXPECT_EQ(new_array[i], vec[pos]);
    295    ++pos;
    296  }
    297 }
    298 
    299 // Test the InsertAt method with an insert position beyond the end of the
    300 // vector. Verify that a position beyond the end of the vector does not lead to
    301 // an error. The expected outcome is the same as if the vector end was used as
    302 // input position. That is, the input position should be capped at the maximum
    303 // allowed value.
    304 TEST_F(AudioVectorTest, InsertBeyondEnd) {
    305  AudioVector vec;
    306  vec.PushBack(array_, array_length());
    307  static const int kNewLength = 5;
    308  int16_t new_array[kNewLength];
    309  // Set array elements to {100, 101, 102, ... }.
    310  for (int i = 0; i < kNewLength; ++i) {
    311    new_array[i] = 100 + i;
    312  }
    313  int insert_position = checked_cast<int>(array_length() + 10);  // Too large.
    314  vec.InsertAt(new_array, kNewLength, insert_position);
    315  // Verify that the vector looks as follows:
    316  // {0, 1, ..., kLength - 1, 100, 101, ..., 100 + kNewLength - 1 }.
    317  size_t pos = 0;
    318  for (size_t i = 0; i < array_length(); ++i) {
    319    EXPECT_EQ(array_[i], vec[pos]);
    320    ++pos;
    321  }
    322  for (int i = 0; i < kNewLength; ++i) {
    323    EXPECT_EQ(new_array[i], vec[pos]);
    324    ++pos;
    325  }
    326 }
    327 
    328 // Test the OverwriteAt method with a position such that all of the new values
    329 // fit within the old vector.
    330 TEST_F(AudioVectorTest, OverwriteAt) {
    331  AudioVector vec;
    332  vec.PushBack(array_, array_length());
    333  static const int kNewLength = 5;
    334  int16_t new_array[kNewLength];
    335  // Set array elements to {100, 101, 102, ... }.
    336  for (int i = 0; i < kNewLength; ++i) {
    337    new_array[i] = 100 + i;
    338  }
    339  size_t insert_position = 2;
    340  vec.OverwriteAt(new_array, kNewLength, insert_position);
    341  // Verify that the vector looks as follows:
    342  // {0, ..., `insert_position` - 1, 100, 101, ..., 100 + kNewLength - 1,
    343  //  `insert_position`, `insert_position` + 1, ..., kLength - 1}.
    344  size_t pos = 0;
    345  for (pos = 0; pos < insert_position; ++pos) {
    346    EXPECT_EQ(array_[pos], vec[pos]);
    347  }
    348  for (int i = 0; i < kNewLength; ++i) {
    349    EXPECT_EQ(new_array[i], vec[pos]);
    350    ++pos;
    351  }
    352  for (; pos < array_length(); ++pos) {
    353    EXPECT_EQ(array_[pos], vec[pos]);
    354  }
    355 }
    356 
    357 // Test the OverwriteAt method with a position such that some of the new values
    358 // extend beyond the end of the current vector. This is valid, and the vector is
    359 // expected to expand to accommodate the new values.
    360 TEST_F(AudioVectorTest, OverwriteBeyondEnd) {
    361  AudioVector vec;
    362  vec.PushBack(array_, array_length());
    363  static const int kNewLength = 5;
    364  int16_t new_array[kNewLength];
    365  // Set array elements to {100, 101, 102, ... }.
    366  for (int i = 0; i < kNewLength; ++i) {
    367    new_array[i] = 100 + i;
    368  }
    369  int insert_position = checked_cast<int>(array_length() - 2);
    370  vec.OverwriteAt(new_array, kNewLength, insert_position);
    371  ASSERT_EQ(array_length() - 2u + kNewLength, vec.Size());
    372  // Verify that the vector looks as follows:
    373  // {0, ..., `insert_position` - 1, 100, 101, ..., 100 + kNewLength - 1,
    374  //  `insert_position`, `insert_position` + 1, ..., kLength - 1}.
    375  int pos = 0;
    376  for (pos = 0; pos < insert_position; ++pos) {
    377    EXPECT_EQ(array_[pos], vec[pos]);
    378  }
    379  for (int i = 0; i < kNewLength; ++i) {
    380    EXPECT_EQ(new_array[i], vec[pos]);
    381    ++pos;
    382  }
    383  // Verify that we checked to the end of `vec`.
    384  EXPECT_EQ(vec.Size(), static_cast<size_t>(pos));
    385 }
    386 
    387 TEST_F(AudioVectorTest, CrossFade) {
    388  static const size_t kLength = 100;
    389  static const size_t kFadeLength = 10;
    390  AudioVector vec1(kLength);
    391  AudioVector vec2(kLength);
    392  // Set all vector elements to 0 in `vec1` and 100 in `vec2`.
    393  for (size_t i = 0; i < kLength; ++i) {
    394    vec1[i] = 0;
    395    vec2[i] = 100;
    396  }
    397  vec1.CrossFade(vec2, kFadeLength);
    398  ASSERT_EQ(2 * kLength - kFadeLength, vec1.Size());
    399  // First part untouched.
    400  for (size_t i = 0; i < kLength - kFadeLength; ++i) {
    401    EXPECT_EQ(0, vec1[i]);
    402  }
    403  // Check mixing zone.
    404  for (size_t i = 0; i < kFadeLength; ++i) {
    405    EXPECT_NEAR((i + 1) * 100 / (kFadeLength + 1),
    406                vec1[kLength - kFadeLength + i], 1);
    407  }
    408  // Second part untouched.
    409  for (size_t i = kLength; i < vec1.Size(); ++i) {
    410    EXPECT_EQ(100, vec1[i]);
    411  }
    412 }
    413 
    414 }  // namespace webrtc