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