/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/audio_coding/neteq/sync_buffer.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace webrtc {

TEST(SyncBuffer, CreateAndDestroy) {
  // Create a SyncBuffer with two channels and 10 samples each.
  static const size_t kLen = 10;
  static const size_t kChannels = 2;
  SyncBuffer sync_buffer(kChannels, kLen);
  EXPECT_EQ(kChannels, sync_buffer.Channels());
  EXPECT_EQ(kLen, sync_buffer.Size());
  // When the buffer is empty, the next index to play out is at the end.
  EXPECT_EQ(kLen, sync_buffer.next_index());
  // Verify that all elements are zero.
  for (size_t channel = 0; channel < kChannels; ++channel) {
    for (size_t i = 0; i < kLen; ++i) {
      EXPECT_EQ(0, sync_buffer[channel][i]);
    }
  }
}

TEST(SyncBuffer, SetNextIndex) {
  // Create a SyncBuffer with two channels and 100 samples each.
  static const size_t kLen = 100;
  static const size_t kChannels = 2;
  SyncBuffer sync_buffer(kChannels, kLen);
  sync_buffer.set_next_index(0);
  EXPECT_EQ(0u, sync_buffer.next_index());
  sync_buffer.set_next_index(kLen / 2);
  EXPECT_EQ(kLen / 2, sync_buffer.next_index());
  sync_buffer.set_next_index(kLen);
  EXPECT_EQ(kLen, sync_buffer.next_index());
  // Try to set larger than the buffer size; should cap at buffer size.
  sync_buffer.set_next_index(kLen + 1);
  EXPECT_EQ(kLen, sync_buffer.next_index());
}

TEST(SyncBuffer, PushBackAndFlush) {
  // Create a SyncBuffer with two channels and 100 samples each.
  static const size_t kLen = 100;
  static const size_t kChannels = 2;
  SyncBuffer sync_buffer(kChannels, kLen);
  static const size_t kNewLen = 10;
  AudioMultiVector new_data(kChannels, kNewLen);
  // Populate |new_data|.
  for (size_t channel = 0; channel < kChannels; ++channel) {
    for (size_t i = 0; i < kNewLen; ++i) {
      new_data[channel][i] = i;
    }
  }
  // Push back |new_data| into |sync_buffer|. This operation should pop out
  // data from the front of |sync_buffer|, so that the size of the buffer
  // remains the same. The |next_index_| should also move with the same length.
  sync_buffer.PushBack(new_data);
  ASSERT_EQ(kLen, sync_buffer.Size());
  // Verify that |next_index_| moved accordingly.
  EXPECT_EQ(kLen - kNewLen, sync_buffer.next_index());
  // Verify the new contents.
  for (size_t channel = 0; channel < kChannels; ++channel) {
    for (size_t i = 0; i < kNewLen; ++i) {
      EXPECT_EQ(new_data[channel][i],
                sync_buffer[channel][sync_buffer.next_index() + i]);
    }
  }

  // Now flush the buffer, and verify that it is all zeros, and that next_index
  // points to the end.
  sync_buffer.Flush();
  ASSERT_EQ(kLen, sync_buffer.Size());
  EXPECT_EQ(kLen, sync_buffer.next_index());
  for (size_t channel = 0; channel < kChannels; ++channel) {
    for (size_t i = 0; i < kLen; ++i) {
      EXPECT_EQ(0, sync_buffer[channel][i]);
    }
  }
}

TEST(SyncBuffer, PushFrontZeros) {
  // Create a SyncBuffer with two channels and 100 samples each.
  static const size_t kLen = 100;
  static const size_t kChannels = 2;
  SyncBuffer sync_buffer(kChannels, kLen);
  static const size_t kNewLen = 10;
  AudioMultiVector new_data(kChannels, kNewLen);
  // Populate |new_data|.
  for (size_t channel = 0; channel < kChannels; ++channel) {
    for (size_t i = 0; i < kNewLen; ++i) {
      new_data[channel][i] = 1000 + i;
    }
  }
  sync_buffer.PushBack(new_data);
  EXPECT_EQ(kLen, sync_buffer.Size());

  // Push |kNewLen| - 1 zeros into each channel in the front of the SyncBuffer.
  sync_buffer.PushFrontZeros(kNewLen - 1);
  EXPECT_EQ(kLen, sync_buffer.Size());  // Size should remain the same.
  // Verify that |next_index_| moved accordingly. Should be at the end - 1.
  EXPECT_EQ(kLen - 1, sync_buffer.next_index());
  // Verify the zeros.
  for (size_t channel = 0; channel < kChannels; ++channel) {
    for (size_t i = 0; i < kNewLen - 1; ++i) {
      EXPECT_EQ(0, sync_buffer[channel][i]);
    }
  }
  // Verify that the correct data is at the end of the SyncBuffer.
  for (size_t channel = 0; channel < kChannels; ++channel) {
    EXPECT_EQ(1000, sync_buffer[channel][sync_buffer.next_index()]);
  }
}

TEST(SyncBuffer, GetNextAudioInterleaved) {
  // Create a SyncBuffer with two channels and 100 samples each.
  static const size_t kLen = 100;
  static const size_t kChannels = 2;
  SyncBuffer sync_buffer(kChannels, kLen);
  static const size_t kNewLen = 10;
  AudioMultiVector new_data(kChannels, kNewLen);
  // Populate |new_data|.
  for (size_t channel = 0; channel < kChannels; ++channel) {
    for (size_t i = 0; i < kNewLen; ++i) {
      new_data[channel][i] = i;
    }
  }
  // Push back |new_data| into |sync_buffer|. This operation should pop out
  // data from the front of |sync_buffer|, so that the size of the buffer
  // remains the same. The |next_index_| should also move with the same length.
  sync_buffer.PushBack(new_data);

  // Read to interleaved output. Read in two batches, where each read operation
  // should automatically update the |net_index_| in the SyncBuffer.
  // Note that |samples_read| is the number of samples read from each channel.
  // That is, the number of samples written to |output| is
  // |samples_read| * |kChannels|.
  AudioFrame output1;
  sync_buffer.GetNextAudioInterleaved(kNewLen / 2, &output1);
  EXPECT_EQ(kChannels, output1.num_channels_);
  EXPECT_EQ(kNewLen / 2, output1.samples_per_channel_);

  AudioFrame output2;
  sync_buffer.GetNextAudioInterleaved(kNewLen / 2, &output2);
  EXPECT_EQ(kChannels, output2.num_channels_);
  EXPECT_EQ(kNewLen / 2, output2.samples_per_channel_);

  // Verify the data.
  int16_t* output_ptr = output1.data_;
  for (size_t i = 0; i < kNewLen / 2; ++i) {
    for (size_t channel = 0; channel < kChannels; ++channel) {
      EXPECT_EQ(new_data[channel][i], *output_ptr);
      ++output_ptr;
    }
  }
  output_ptr = output2.data_;
  for (size_t i = kNewLen / 2; i < kNewLen; ++i) {
    for (size_t channel = 0; channel < kChannels; ++channel) {
      EXPECT_EQ(new_data[channel][i], *output_ptr);
      ++output_ptr;
    }
  }
}

}  // namespace webrtc
