19a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org/*
29a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
39a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *
49a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  Use of this source code is governed by a BSD-style license
59a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  that can be found in the LICENSE file in the root of the source
69a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  tree. An additional intellectual property rights grant can be found
79a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  in the file PATENTS.  All contributing project authors may
89a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
99a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org */
109a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
11e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h"
129a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
139a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include <assert.h>
149a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include <stdlib.h>
159a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
169a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include <string>
179a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1849d62206ededc5905d6121d42fdcce8ed665b2c0kjellander@webrtc.org#include "testing/gtest/include/gtest/gtest.h"
199a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include "webrtc/typedefs.h"
209a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
219a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgnamespace webrtc {
229a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
239a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// This is a value-parameterized test. The test cases are instantiated with
249a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// different values for the test parameter, which is used to determine the
259a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// number of channels in the AudioMultiBuffer. Note that it is not possible
269a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// to combine typed testing with value-parameterized testing, and since the
279a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// tests for AudioVector already covers a number of different type parameters,
289a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// this test focuses on testing different number of channels, and keeping the
299a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// value type constant.
3098b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org
319a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgclass AudioMultiVectorTest : public ::testing::TestWithParam<size_t> {
329a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org protected:
339a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  AudioMultiVectorTest()
349a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      : num_channels_(GetParam()),  // Get the test parameter.
3598b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org        interleaved_length_(num_channels_ * array_length()) {
360e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org    array_interleaved_ = new int16_t[num_channels_ * array_length()];
379a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
389a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
399a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  ~AudioMultiVectorTest() {
409a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    delete [] array_interleaved_;
419a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
429a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
439a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  virtual void SetUp() {
449a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // Populate test arrays.
4598b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org    for (size_t i = 0; i < array_length(); ++i) {
460e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org      array_[i] = static_cast<int16_t>(i);
479a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
480e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org    int16_t* ptr = array_interleaved_;
499a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // Write 100, 101, 102, ... for first channel.
509a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // Write 200, 201, 202, ... for second channel.
519a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // And so on.
5298b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org    for (size_t i = 0; i < array_length(); ++i) {
539a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      for (size_t j = 1; j <= num_channels_; ++j) {
549a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        *ptr = j * 100 + i;
559a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        ++ptr;
569a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      }
579a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
589a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
599a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
6098b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  size_t array_length() const {
6198b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org    return sizeof(array_) / sizeof(array_[0]);
6298b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  }
639a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
649a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  const size_t num_channels_;
659a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  size_t interleaved_length_;
660e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  int16_t array_[10];
670e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  int16_t* array_interleaved_;
689a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org};
699a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
709a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Create and destroy AudioMultiVector objects, both empty and with a predefined
719a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// length.
729a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, CreateAndDestroy) {
730e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec1(num_channels_);
749a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_TRUE(vec1.Empty());
759a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_EQ(num_channels_, vec1.Channels());
769a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_EQ(0u, vec1.Size());
779a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
789a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  size_t initial_size = 17;
790e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec2(num_channels_, initial_size);
809a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_FALSE(vec2.Empty());
819a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_EQ(num_channels_, vec2.Channels());
829a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_EQ(initial_size, vec2.Size());
839a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
849a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
859a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Test the subscript operator [] for getting and setting.
869a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, SubscriptOperator) {
870e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec(num_channels_, array_length());
889a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  for (size_t channel = 0; channel < num_channels_; ++channel) {
8998b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org    for (size_t i = 0; i < array_length(); ++i) {
900e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org      vec[channel][i] = static_cast<int16_t>(i);
919a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      // Make sure to use the const version.
929b1b52533c0e6accb1b0d3a4c1934856cd4473edhenrik.lundin@webrtc.org      const AudioVector& audio_vec = vec[channel];
930e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org      EXPECT_EQ(static_cast<int16_t>(i), audio_vec[i]);
949a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
959a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
969a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
979a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
989a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Test the PushBackInterleaved method and the CopyFrom method. The Clear
999a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// method is also invoked.
1009a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, PushBackInterleavedAndCopy) {
1010e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec(num_channels_);
1029a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
1030e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec_copy(num_channels_);
1040e4084a5b020b0364983acde9d4d420db876995ahenrik.lundin@webrtc.org  vec.CopyTo(&vec_copy);  // Copy from |vec| to |vec_copy|.
1059a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  ASSERT_EQ(num_channels_, vec.Channels());
10698b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  ASSERT_EQ(array_length(), vec.Size());
1079a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  ASSERT_EQ(num_channels_, vec_copy.Channels());
10898b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  ASSERT_EQ(array_length(), vec_copy.Size());
1099a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  for (size_t channel = 0; channel < vec.Channels(); ++channel) {
11098b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org    for (size_t i = 0; i < array_length(); ++i) {
1110e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org      EXPECT_EQ(static_cast<int16_t>((channel + 1) * 100 + i), vec[channel][i]);
1129a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      EXPECT_EQ(vec[channel][i], vec_copy[channel][i]);
1139a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1149a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
1159a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1169a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Clear |vec| and verify that it is empty.
1179a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec.Clear();
1189a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_TRUE(vec.Empty());
1199a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1209a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Now copy the empty vector and verify that the copy becomes empty too.
1210e4084a5b020b0364983acde9d4d420db876995ahenrik.lundin@webrtc.org  vec.CopyTo(&vec_copy);
1229a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_TRUE(vec_copy.Empty());
1239a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
1249a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1259a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Try to copy to a NULL pointer. Nothing should happen.
1269a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, CopyToNull) {
1270e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec(num_channels_);
1280e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector* vec_copy = NULL;
1299a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
1300e4084a5b020b0364983acde9d4d420db876995ahenrik.lundin@webrtc.org  vec.CopyTo(vec_copy);
1319a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
1329a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1339a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Test the PushBack method with another AudioMultiVector as input argument.
1349a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, PushBackVector) {
1350e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec1(num_channels_, array_length());
1360e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec2(num_channels_, array_length());
13798b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  // Set the first vector to [0, 1, ..., array_length() - 1] +
13898b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  //   100 * channel_number.
13998b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  // Set the second vector to [array_length(), array_length() + 1, ...,
14098b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  //   2 * array_length() - 1] + 100 * channel_number.
1419a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  for (size_t channel = 0; channel < num_channels_; ++channel) {
14298b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org    for (size_t i = 0; i < array_length(); ++i) {
1430e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org      vec1[channel][i] = static_cast<int16_t>(i + 100 * channel);
1440e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org      vec2[channel][i] =
1450e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org          static_cast<int16_t>(i + 100 * channel + array_length());
1469a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1479a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
1489a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Append vec2 to the back of vec1.
1499a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec1.PushBack(vec2);
15098b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  ASSERT_EQ(2u * array_length(), vec1.Size());
1519a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  for (size_t channel = 0; channel < num_channels_; ++channel) {
15298b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org    for (size_t i = 0; i < 2 * array_length(); ++i) {
1530e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org      EXPECT_EQ(static_cast<int16_t>(i + 100 * channel), vec1[channel][i]);
1549a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1559a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
1569a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
1579a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1589a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Test the PushBackFromIndex method.
1599a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, PushBackFromIndex) {
1600e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec1(num_channels_);
1619a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec1.PushBackInterleaved(array_interleaved_, interleaved_length_);
1620e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec2(num_channels_);
1639a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1649a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Append vec1 to the back of vec2 (which is empty). Read vec1 from the second
1659a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // last element.
16698b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  vec2.PushBackFromIndex(vec1, array_length() - 2);
1679a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  ASSERT_EQ(2u, vec2.Size());
1689a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  for (size_t channel = 0; channel < num_channels_; ++channel) {
1699a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    for (size_t i = 0; i < 2; ++i) {
17098b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org      EXPECT_EQ(array_interleaved_[channel + num_channels_ *
17198b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org                  (array_length() - 2 + i)], vec2[channel][i]);
1729a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1739a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
1749a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
1759a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1769a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Starts with pushing some values to the vector, then test the Zeros method.
1779a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, Zeros) {
1780e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec(num_channels_);
1799a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
18098b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  vec.Zeros(2 * array_length());
1819a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  ASSERT_EQ(num_channels_, vec.Channels());
18298b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  ASSERT_EQ(2u * array_length(), vec.Size());
1839a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  for (size_t channel = 0; channel < num_channels_; ++channel) {
18498b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org    for (size_t i = 0; i < 2 * array_length(); ++i) {
1859a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      EXPECT_EQ(0, vec[channel][i]);
1869a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1879a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
1889a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
1899a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1909a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Test the ReadInterleaved method
1919a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, ReadInterleaved) {
1920e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec(num_channels_);
1939a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
1940e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  int16_t* output = new int16_t[interleaved_length_];
1959a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Read 5 samples.
1969a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  size_t read_samples = 5;
1979a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_EQ(num_channels_ * read_samples,
1989a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org            vec.ReadInterleaved(read_samples, output));
1990e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  EXPECT_EQ(0,
2000e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org            memcmp(array_interleaved_, output, read_samples * sizeof(int16_t)));
2019a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
2029a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Read too many samples. Expect to get all samples from the vector.
2039a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_EQ(interleaved_length_,
20498b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org            vec.ReadInterleaved(array_length() + 1, output));
2050e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  EXPECT_EQ(0,
2060e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org            memcmp(array_interleaved_, output, read_samples * sizeof(int16_t)));
2079a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
2089a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  delete [] output;
2099a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
2109a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
2119a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Try to read to a NULL pointer. Expected to return 0.
2129a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, ReadInterleavedToNull) {
2130e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec(num_channels_);
2149a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
2150e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  int16_t* output = NULL;
2169a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Read 5 samples.
2179a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  size_t read_samples = 5;
2189a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_EQ(0u, vec.ReadInterleaved(read_samples, output));
2199a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
2209a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
2219a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Test the PopFront method.
2229a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, PopFront) {
2230e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec(num_channels_);
2249a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
2259a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec.PopFront(1);  // Remove one element from each channel.
22698b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  ASSERT_EQ(array_length() - 1u, vec.Size());
2279a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Let |ptr| point to the second element of the first channel in the
2289a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // interleaved array.
2290e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  int16_t* ptr = &array_interleaved_[num_channels_];
23098b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  for (size_t i = 0; i < array_length() - 1; ++i) {
2319a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    for (size_t channel = 0; channel < num_channels_; ++channel) {
2329a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      EXPECT_EQ(*ptr, vec[channel][i]);
2339a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      ++ptr;
2349a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
2359a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
23698b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  vec.PopFront(array_length());  // Remove more elements than vector size.
2379a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_EQ(0u, vec.Size());
2389a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
2399a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
2409a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Test the PopBack method.
2419a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, PopBack) {
2420e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec(num_channels_);
2439a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
2449a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec.PopBack(1);  // Remove one element from each channel.
24598b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  ASSERT_EQ(array_length() - 1u, vec.Size());
2469a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Let |ptr| point to the first element of the first channel in the
2479a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // interleaved array.
2480e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  int16_t* ptr = array_interleaved_;
24998b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  for (size_t i = 0; i < array_length() - 1; ++i) {
2509a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    for (size_t channel = 0; channel < num_channels_; ++channel) {
2519a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      EXPECT_EQ(*ptr, vec[channel][i]);
2529a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      ++ptr;
2539a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
2549a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
25598b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  vec.PopBack(array_length());  // Remove more elements than vector size.
2569a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  EXPECT_EQ(0u, vec.Size());
2579a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
2589a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
2599a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Test the AssertSize method.
2609a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, AssertSize) {
2610e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec(num_channels_, array_length());
26298b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  EXPECT_EQ(array_length(), vec.Size());
2639a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Start with asserting with smaller sizes than already allocated.
2649a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec.AssertSize(0);
26598b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  vec.AssertSize(array_length() - 1);
2669a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Nothing should have changed.
26798b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  EXPECT_EQ(array_length(), vec.Size());
2689a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Assert with one element longer than already allocated.
26998b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  vec.AssertSize(array_length() + 1);
2709a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Expect vector to have grown.
27198b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  EXPECT_EQ(array_length() + 1, vec.Size());
2729a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Also check the individual AudioVectors.
2739a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  for (size_t channel = 0; channel < vec.Channels(); ++channel) {
27498b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org    EXPECT_EQ(array_length() + 1u, vec[channel].Size());
2759a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
2769a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
2779a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
2789a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Test the PushBack method with another AudioMultiVector as input argument.
2799a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, OverwriteAt) {
2800e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec1(num_channels_);
2819a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec1.PushBackInterleaved(array_interleaved_, interleaved_length_);
2820e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  AudioMultiVector vec2(num_channels_);
2839a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec2.Zeros(3);  // 3 zeros in each channel.
2849a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Overwrite vec2 at position 5.
2859a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  vec1.OverwriteAt(vec2, 3, 5);
2869a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Verify result.
28798b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  // Length remains the same.
28898b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  ASSERT_EQ(array_length(), vec1.Size());
2890e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  int16_t* ptr = array_interleaved_;
29098b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org  for (size_t i = 0; i < array_length() - 1; ++i) {
2919a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    for (size_t channel = 0; channel < num_channels_; ++channel) {
2929a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      if (i >= 5 && i <= 7) {
2939a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        // Elements 5, 6, 7 should have been replaced with zeros.
2949a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        EXPECT_EQ(0, vec1[channel][i]);
2959a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      } else {
2969a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        EXPECT_EQ(*ptr, vec1[channel][i]);
2979a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      }
2989a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      ++ptr;
2999a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
3009a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  }
3019a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
3029a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
303d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org// Test the CopyChannel method, when the test is instantiated with at least two
304d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org// channels.
305d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.orgTEST_P(AudioMultiVectorTest, CopyChannel) {
306d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  if (num_channels_ < 2)
307d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org    return;
308d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org
309d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  AudioMultiVector vec(num_channels_);
310d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
311d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  // Create a reference copy.
312d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  AudioMultiVector ref(num_channels_);
313d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  ref.PushBack(vec);
314d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  // Copy from first to last channel.
315d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  vec.CopyChannel(0, num_channels_ - 1);
316d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  // Verify that the first and last channels are identical; the others should
317d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  // be left untouched.
318d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  for (size_t i = 0; i < array_length(); ++i) {
319d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org    // Verify that all but the last channel are untouched.
320d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org    for (size_t channel = 0; channel < num_channels_ - 1; ++channel) {
321d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org      EXPECT_EQ(ref[channel][i], vec[channel][i]);
322d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org    }
323d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org    // Verify that the last and the first channels are identical.
324d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org    EXPECT_EQ(vec[0][i], vec[num_channels_ - 1][i]);
325d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org  }
326d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org}
327d4fa81febd85b072fea77822c07958bffca13b8ahenrik.lundin@webrtc.org
3289a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgINSTANTIATE_TEST_CASE_P(TestNumChannels,
3299a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                        AudioMultiVectorTest,
3309a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                        ::testing::Values(static_cast<size_t>(1),
3319a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                                          static_cast<size_t>(2),
3329a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                                          static_cast<size_t>(5)));
3339a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}  // namespace webrtc
334