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/sync_buffer.h"
12
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace webrtc {
16
17TEST(SyncBuffer, CreateAndDestroy) {
18  // Create a SyncBuffer with two channels and 10 samples each.
19  static const size_t kLen = 10;
20  static const size_t kChannels = 2;
21  SyncBuffer sync_buffer(kChannels, kLen);
22  EXPECT_EQ(kChannels, sync_buffer.Channels());
23  EXPECT_EQ(kLen, sync_buffer.Size());
24  // When the buffer is empty, the next index to play out is at the end.
25  EXPECT_EQ(kLen, sync_buffer.next_index());
26  // Verify that all elements are zero.
27  for (size_t channel = 0; channel < kChannels; ++channel) {
28    for (size_t i = 0; i < kLen; ++i) {
29      EXPECT_EQ(0, sync_buffer[channel][i]);
30    }
31  }
32}
33
34TEST(SyncBuffer, SetNextIndex) {
35  // Create a SyncBuffer with two channels and 100 samples each.
36  static const size_t kLen = 100;
37  static const size_t kChannels = 2;
38  SyncBuffer sync_buffer(kChannels, kLen);
39  sync_buffer.set_next_index(0);
40  EXPECT_EQ(0u, sync_buffer.next_index());
41  sync_buffer.set_next_index(kLen / 2);
42  EXPECT_EQ(kLen / 2, sync_buffer.next_index());
43  sync_buffer.set_next_index(kLen);
44  EXPECT_EQ(kLen, sync_buffer.next_index());
45  // Try to set larger than the buffer size; should cap at buffer size.
46  sync_buffer.set_next_index(kLen + 1);
47  EXPECT_EQ(kLen, sync_buffer.next_index());
48}
49
50TEST(SyncBuffer, PushBackAndFlush) {
51  // Create a SyncBuffer with two channels and 100 samples each.
52  static const size_t kLen = 100;
53  static const size_t kChannels = 2;
54  SyncBuffer sync_buffer(kChannels, kLen);
55  static const size_t kNewLen = 10;
56  AudioMultiVector new_data(kChannels, kNewLen);
57  // Populate |new_data|.
58  for (size_t channel = 0; channel < kChannels; ++channel) {
59    for (size_t i = 0; i < kNewLen; ++i) {
60      new_data[channel][i] = i;
61    }
62  }
63  // Push back |new_data| into |sync_buffer|. This operation should pop out
64  // data from the front of |sync_buffer|, so that the size of the buffer
65  // remains the same. The |next_index_| should also move with the same length.
66  sync_buffer.PushBack(new_data);
67  ASSERT_EQ(kLen, sync_buffer.Size());
68  // Verify that |next_index_| moved accordingly.
69  EXPECT_EQ(kLen - kNewLen, sync_buffer.next_index());
70  // Verify the new contents.
71  for (size_t channel = 0; channel < kChannels; ++channel) {
72    for (size_t i = 0; i < kNewLen; ++i) {
73      EXPECT_EQ(new_data[channel][i],
74                sync_buffer[channel][sync_buffer.next_index() + i]);
75    }
76  }
77
78  // Now flush the buffer, and verify that it is all zeros, and that next_index
79  // points to the end.
80  sync_buffer.Flush();
81  ASSERT_EQ(kLen, sync_buffer.Size());
82  EXPECT_EQ(kLen, sync_buffer.next_index());
83  for (size_t channel = 0; channel < kChannels; ++channel) {
84    for (size_t i = 0; i < kLen; ++i) {
85      EXPECT_EQ(0, sync_buffer[channel][i]);
86    }
87  }
88}
89
90TEST(SyncBuffer, PushFrontZeros) {
91  // Create a SyncBuffer with two channels and 100 samples each.
92  static const size_t kLen = 100;
93  static const size_t kChannels = 2;
94  SyncBuffer sync_buffer(kChannels, kLen);
95  static const size_t kNewLen = 10;
96  AudioMultiVector new_data(kChannels, kNewLen);
97  // Populate |new_data|.
98  for (size_t channel = 0; channel < kChannels; ++channel) {
99    for (size_t i = 0; i < kNewLen; ++i) {
100      new_data[channel][i] = 1000 + i;
101    }
102  }
103  sync_buffer.PushBack(new_data);
104  EXPECT_EQ(kLen, sync_buffer.Size());
105
106  // Push |kNewLen| - 1 zeros into each channel in the front of the SyncBuffer.
107  sync_buffer.PushFrontZeros(kNewLen - 1);
108  EXPECT_EQ(kLen, sync_buffer.Size());  // Size should remain the same.
109  // Verify that |next_index_| moved accordingly. Should be at the end - 1.
110  EXPECT_EQ(kLen - 1, sync_buffer.next_index());
111  // Verify the zeros.
112  for (size_t channel = 0; channel < kChannels; ++channel) {
113    for (size_t i = 0; i < kNewLen - 1; ++i) {
114      EXPECT_EQ(0, sync_buffer[channel][i]);
115    }
116  }
117  // Verify that the correct data is at the end of the SyncBuffer.
118  for (size_t channel = 0; channel < kChannels; ++channel) {
119    EXPECT_EQ(1000, sync_buffer[channel][sync_buffer.next_index()]);
120  }
121}
122
123TEST(SyncBuffer, GetNextAudioInterleaved) {
124  // Create a SyncBuffer with two channels and 100 samples each.
125  static const size_t kLen = 100;
126  static const size_t kChannels = 2;
127  SyncBuffer sync_buffer(kChannels, kLen);
128  static const size_t kNewLen = 10;
129  AudioMultiVector new_data(kChannels, kNewLen);
130  // Populate |new_data|.
131  for (size_t channel = 0; channel < kChannels; ++channel) {
132    for (size_t i = 0; i < kNewLen; ++i) {
133      new_data[channel][i] = i;
134    }
135  }
136  // Push back |new_data| into |sync_buffer|. This operation should pop out
137  // data from the front of |sync_buffer|, so that the size of the buffer
138  // remains the same. The |next_index_| should also move with the same length.
139  sync_buffer.PushBack(new_data);
140
141  // Read to interleaved output. Read in two batches, where each read operation
142  // should automatically update the |net_index_| in the SyncBuffer.
143  int16_t output[kChannels * kNewLen];
144  // Note that |samples_read| is the number of samples read from each channel.
145  // That is, the number of samples written to |output| is
146  // |samples_read| * |kChannels|.
147  size_t samples_read = sync_buffer.GetNextAudioInterleaved(kNewLen / 2,
148                                                            output);
149  samples_read +=
150      sync_buffer.GetNextAudioInterleaved(kNewLen / 2,
151                                          &output[samples_read * kChannels]);
152  EXPECT_EQ(kNewLen, samples_read);
153
154  // Verify the data.
155  int16_t* output_ptr = output;
156  for (size_t i = 0; i < kNewLen; ++i) {
157    for (size_t channel = 0; channel < kChannels; ++channel) {
158      EXPECT_EQ(new_data[channel][i], *output_ptr);
159      ++output_ptr;
160    }
161  }
162}
163
164}  // namespace webrtc
165