audio_buffer_unittest.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/strings/string_util.h"
6#include "base/strings/stringprintf.h"
7#include "media/base/audio_buffer.h"
8#include "media/base/audio_bus.h"
9#include "media/base/test_helpers.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace media {
13
14const static int kSampleRate = 44100;
15
16static void VerifyResult(float* channel_data,
17                         int frames,
18                         float start,
19                         float increment) {
20  for (int i = 0; i < frames; ++i) {
21    SCOPED_TRACE(base::StringPrintf(
22        "i=%d/%d start=%f, increment=%f", i, frames, start, increment));
23    ASSERT_EQ(channel_data[i], start);
24    start += increment;
25  }
26}
27
28TEST(AudioBufferTest, CopyFrom) {
29  const ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO;
30  const int frames = 8;
31  const base::TimeDelta start_time;
32  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
33  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<uint8>(kSampleFormatU8,
34                                                             channel_layout,
35                                                             kSampleRate,
36                                                             1,
37                                                             1,
38                                                             frames,
39                                                             start_time,
40                                                             duration);
41  EXPECT_EQ(frames, buffer->frame_count());
42  EXPECT_EQ(buffer->timestamp(), start_time);
43  EXPECT_EQ(buffer->duration().InSeconds(), frames);
44  EXPECT_FALSE(buffer->end_of_stream());
45}
46
47TEST(AudioBufferTest, CreateEOSBuffer) {
48  scoped_refptr<AudioBuffer> buffer = AudioBuffer::CreateEOSBuffer();
49  EXPECT_TRUE(buffer->end_of_stream());
50}
51
52TEST(AudioBufferTest, FrameSize) {
53  const uint8 kTestData[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
54                              15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
55                              27, 28, 29, 30, 31 };
56  const base::TimeDelta kTimestampA = base::TimeDelta::FromMicroseconds(1337);
57  const base::TimeDelta kTimestampB = base::TimeDelta::FromMicroseconds(1234);
58
59  const uint8* const data[] = { kTestData };
60  scoped_refptr<AudioBuffer> buffer =
61      AudioBuffer::CopyFrom(kSampleFormatU8,
62                            CHANNEL_LAYOUT_STEREO,
63                            kSampleRate,
64                            16,
65                            data,
66                            kTimestampA,
67                            kTimestampB);
68  EXPECT_EQ(16, buffer->frame_count());  // 2 channels of 8-bit data
69
70  buffer = AudioBuffer::CopyFrom(kSampleFormatF32,
71                                 CHANNEL_LAYOUT_4_0,
72                                 kSampleRate,
73                                 2,
74                                 data,
75                                 kTimestampA,
76                                 kTimestampB);
77  EXPECT_EQ(2, buffer->frame_count());  // now 4 channels of 32-bit data
78}
79
80TEST(AudioBufferTest, ReadU8) {
81  const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
82  const int channels = ChannelLayoutToChannelCount(channel_layout);
83  const int frames = 4;
84  const base::TimeDelta start_time;
85  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
86  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<uint8>(kSampleFormatU8,
87                                                             channel_layout,
88                                                             kSampleRate,
89                                                             128,
90                                                             1,
91                                                             frames,
92                                                             start_time,
93                                                             duration);
94
95  // Read all 4 frames from the buffer. Data is interleaved, so ch[0] should be
96  // 128, 132, 136, 140, other channels similar. However, values are converted
97  // from [0, 255] to [-1.0, 1.0] with a bias of 128. Thus the first buffer
98  // value should be 0.0, then 1/127, 2/127, etc.
99  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
100  buffer->ReadFrames(frames, 0, 0, bus.get());
101  VerifyResult(bus->channel(0), frames, 0.0f, 4.0f / 127.0f);
102  VerifyResult(bus->channel(1), frames, 1.0f / 127.0f, 4.0f / 127.0f);
103  VerifyResult(bus->channel(2), frames, 2.0f / 127.0f, 4.0f / 127.0f);
104  VerifyResult(bus->channel(3), frames, 3.0f / 127.0f, 4.0f / 127.0f);
105}
106
107TEST(AudioBufferTest, ReadS16) {
108  const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
109  const int channels = ChannelLayoutToChannelCount(channel_layout);
110  const int frames = 10;
111  const base::TimeDelta start_time;
112  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
113  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<int16>(kSampleFormatS16,
114                                                             channel_layout,
115                                                             kSampleRate,
116                                                             1,
117                                                             1,
118                                                             frames,
119                                                             start_time,
120                                                             duration);
121
122  // Read 6 frames from the buffer. Data is interleaved, so ch[0] should be 1,
123  // 3, 5, 7, 9, 11, and ch[1] should be 2, 4, 6, 8, 10, 12. Data is converted
124  // to float from -1.0 to 1.0 based on int16 range.
125  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
126  buffer->ReadFrames(6, 0, 0, bus.get());
127  VerifyResult(bus->channel(0), 6, 1.0f / kint16max, 2.0f / kint16max);
128  VerifyResult(bus->channel(1), 6, 2.0f / kint16max, 2.0f / kint16max);
129
130  // Now read the same data one frame at a time.
131  bus = AudioBus::Create(channels, 100);
132  for (int i = 0; i < frames; ++i) {
133    buffer->ReadFrames(1, i, i, bus.get());
134  }
135  VerifyResult(bus->channel(0), frames, 1.0f / kint16max, 2.0f / kint16max);
136  VerifyResult(bus->channel(1), frames, 2.0f / kint16max, 2.0f / kint16max);
137}
138
139TEST(AudioBufferTest, ReadS32) {
140  const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
141  const int channels = ChannelLayoutToChannelCount(channel_layout);
142  const int frames = 6;
143  const base::TimeDelta start_time;
144  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
145  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<int32>(kSampleFormatS32,
146                                                             channel_layout,
147                                                             kSampleRate,
148                                                             1,
149                                                             1,
150                                                             frames,
151                                                             start_time,
152                                                             duration);
153
154  // Read 6 frames from the buffer. Data is interleaved, so ch[0] should be 1,
155  // 3, 5, 7, 9, 11, and ch[1] should be 2, 4, 6, 8, 10, 12. Data is converted
156  // to float from -1.0 to 1.0 based on int32 range.
157  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
158  buffer->ReadFrames(frames, 0, 0, bus.get());
159  VerifyResult(bus->channel(0), frames, 1.0f / kint32max, 2.0f / kint32max);
160  VerifyResult(bus->channel(1), frames, 2.0f / kint32max, 2.0f / kint32max);
161
162  // Now read 2 frames starting at frame offset 3. ch[0] should be 7, 9, and
163  // ch[1] should be 8, 10.
164  buffer->ReadFrames(2, 3, 0, bus.get());
165  VerifyResult(bus->channel(0), 2, 7.0f / kint32max, 2.0f / kint32max);
166  VerifyResult(bus->channel(1), 2, 8.0f / kint32max, 2.0f / kint32max);
167}
168
169TEST(AudioBufferTest, ReadF32) {
170  const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
171  const int channels = ChannelLayoutToChannelCount(channel_layout);
172  const int frames = 20;
173  const base::TimeDelta start_time;
174  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
175  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<float>(kSampleFormatF32,
176                                                             channel_layout,
177                                                             kSampleRate,
178                                                             1.0f,
179                                                             1.0f,
180                                                             frames,
181                                                             start_time,
182                                                             duration);
183
184  // Read first 10 frames from the buffer. F32 is interleaved, so ch[0] should
185  // be 1, 3, 5, ... and ch[1] should be 2, 4, 6, ...
186  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
187  buffer->ReadFrames(10, 0, 0, bus.get());
188  VerifyResult(bus->channel(0), 10, 1.0f, 2.0f);
189  VerifyResult(bus->channel(1), 10, 2.0f, 2.0f);
190
191  // Read second 10 frames.
192  bus = AudioBus::Create(channels, 100);
193  buffer->ReadFrames(10, 10, 0, bus.get());
194  VerifyResult(bus->channel(0), 10, 21.0f, 2.0f);
195  VerifyResult(bus->channel(1), 10, 22.0f, 2.0f);
196}
197
198TEST(AudioBufferTest, ReadS16Planar) {
199  const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
200  const int channels = ChannelLayoutToChannelCount(channel_layout);
201  const int frames = 20;
202  const base::TimeDelta start_time;
203  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
204  scoped_refptr<AudioBuffer> buffer =
205      MakeAudioBuffer<int16>(kSampleFormatPlanarS16,
206                             channel_layout,
207                             kSampleRate,
208                             1,
209                             1,
210                             frames,
211                             start_time,
212                             duration);
213
214  // Read 6 frames from the buffer. Data is planar, so ch[0] should be 1, 2, 3,
215  // 4, 5, 6, and ch[1] should be 21, 22, 23, 24, 25, 26. Data is converted to
216  // float from -1.0 to 1.0 based on int16 range.
217  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
218  buffer->ReadFrames(6, 0, 0, bus.get());
219  VerifyResult(bus->channel(0), 6, 1.0f / kint16max, 1.0f / kint16max);
220  VerifyResult(bus->channel(1), 6, 21.0f / kint16max, 1.0f / kint16max);
221
222  // Read all the frames backwards, one by one. ch[0] should be 20, 19, ...
223  bus = AudioBus::Create(channels, 100);
224  for (int i = 0; i < frames; ++i) {
225    buffer->ReadFrames(1, frames - i - 1, i, bus.get());
226  }
227  VerifyResult(bus->channel(0), frames, 20.0f / kint16max, -1.0f / kint16max);
228  VerifyResult(bus->channel(1), frames, 40.0f / kint16max, -1.0f / kint16max);
229
230  // Read 0 frames with different offsets. Existing data in AudioBus should be
231  // unchanged.
232  buffer->ReadFrames(0, 0, 0, bus.get());
233  buffer->ReadFrames(0, 0, 10, bus.get());
234  buffer->ReadFrames(0, 10, 0, bus.get());
235  VerifyResult(bus->channel(0), frames, 20.0f / kint16max, -1.0f / kint16max);
236  VerifyResult(bus->channel(1), frames, 40.0f / kint16max, -1.0f / kint16max);
237}
238
239TEST(AudioBufferTest, ReadF32Planar) {
240  const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
241  const int channels = ChannelLayoutToChannelCount(channel_layout);
242  const int frames = 100;
243  const base::TimeDelta start_time;
244  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
245  scoped_refptr<AudioBuffer> buffer =
246      MakeAudioBuffer<float>(kSampleFormatPlanarF32,
247                             channel_layout,
248                             kSampleRate,
249                             1.0f,
250                             1.0f,
251                             frames,
252                             start_time,
253                             duration);
254
255  // Read all 100 frames from the buffer. F32 is planar, so ch[0] should be 1,
256  // 2, 3, 4, ..., ch[1] should be 101, 102, 103, ..., and so on for all 4
257  // channels.
258  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
259  buffer->ReadFrames(frames, 0, 0, bus.get());
260  VerifyResult(bus->channel(0), frames, 1.0f, 1.0f);
261  VerifyResult(bus->channel(1), frames, 101.0f, 1.0f);
262  VerifyResult(bus->channel(2), frames, 201.0f, 1.0f);
263  VerifyResult(bus->channel(3), frames, 301.0f, 1.0f);
264
265  // Now read 20 frames from the middle of the buffer.
266  bus = AudioBus::Create(channels, 100);
267  buffer->ReadFrames(20, 50, 0, bus.get());
268  VerifyResult(bus->channel(0), 20, 51.0f, 1.0f);
269  VerifyResult(bus->channel(1), 20, 151.0f, 1.0f);
270  VerifyResult(bus->channel(2), 20, 251.0f, 1.0f);
271  VerifyResult(bus->channel(3), 20, 351.0f, 1.0f);
272}
273
274TEST(AudioBufferTest, EmptyBuffer) {
275  const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
276  const int channels = ChannelLayoutToChannelCount(channel_layout);
277  const int frames = 100;
278  const base::TimeDelta start_time;
279  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
280  scoped_refptr<AudioBuffer> buffer = AudioBuffer::CreateEmptyBuffer(
281      channel_layout, kSampleRate, frames, start_time, duration);
282  EXPECT_EQ(frames, buffer->frame_count());
283  EXPECT_EQ(start_time, buffer->timestamp());
284  EXPECT_EQ(frames, buffer->duration().InSeconds());
285  EXPECT_FALSE(buffer->end_of_stream());
286
287  // Read all 100 frames from the buffer. All data should be 0.
288  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
289  buffer->ReadFrames(frames, 0, 0, bus.get());
290  VerifyResult(bus->channel(0), frames, 0.0f, 0.0f);
291  VerifyResult(bus->channel(1), frames, 0.0f, 0.0f);
292  VerifyResult(bus->channel(2), frames, 0.0f, 0.0f);
293  VerifyResult(bus->channel(3), frames, 0.0f, 0.0f);
294}
295
296TEST(AudioBufferTest, Trim) {
297  const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
298  const int channels = ChannelLayoutToChannelCount(channel_layout);
299  const int frames = 100;
300  const base::TimeDelta start_time;
301  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
302  scoped_refptr<AudioBuffer> buffer =
303      MakeAudioBuffer<float>(kSampleFormatPlanarF32,
304                             channel_layout,
305                             kSampleRate,
306                             1.0f,
307                             1.0f,
308                             frames,
309                             start_time,
310                             duration);
311  EXPECT_EQ(frames, buffer->frame_count());
312  EXPECT_EQ(start_time, buffer->timestamp());
313  EXPECT_EQ(frames, buffer->duration().InSeconds());
314
315  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
316  buffer->ReadFrames(20, 0, 0, bus.get());
317  VerifyResult(bus->channel(0), 20, 1.0f, 1.0f);
318
319  // Trim off 10 frames from the start.
320  buffer->TrimStart(10);
321  EXPECT_EQ(buffer->frame_count(), frames - 10);
322  EXPECT_EQ(buffer->timestamp(), start_time + base::TimeDelta::FromSeconds(10));
323  EXPECT_EQ(buffer->duration(), base::TimeDelta::FromSeconds(90));
324  buffer->ReadFrames(20, 0, 0, bus.get());
325  VerifyResult(bus->channel(0), 20, 11.0f, 1.0f);
326
327  // Trim off 10 frames from the end.
328  buffer->TrimEnd(10);
329  EXPECT_EQ(buffer->frame_count(), frames - 20);
330  EXPECT_EQ(buffer->timestamp(), start_time + base::TimeDelta::FromSeconds(10));
331  EXPECT_EQ(buffer->duration(), base::TimeDelta::FromSeconds(80));
332  buffer->ReadFrames(20, 0, 0, bus.get());
333  VerifyResult(bus->channel(0), 20, 11.0f, 1.0f);
334
335  // Trim off 50 more from the start.
336  buffer->TrimStart(50);
337  EXPECT_EQ(buffer->frame_count(), frames - 70);
338  EXPECT_EQ(buffer->timestamp(), start_time + base::TimeDelta::FromSeconds(60));
339  EXPECT_EQ(buffer->duration(), base::TimeDelta::FromSeconds(30));
340  buffer->ReadFrames(10, 0, 0, bus.get());
341  VerifyResult(bus->channel(0), 10, 61.0f, 1.0f);
342
343  // Trim off the last 30 frames.
344  buffer->TrimEnd(30);
345  EXPECT_EQ(buffer->frame_count(), 0);
346  EXPECT_EQ(buffer->timestamp(), start_time + base::TimeDelta::FromSeconds(60));
347  EXPECT_EQ(buffer->duration(), base::TimeDelta::FromSeconds(0));
348}
349
350}  // namespace media
351