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