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 "media/base/audio_buffer.h"
6#include "media/base/audio_bus.h"
7#include "media/base/test_helpers.h"
8#include "testing/gtest/include/gtest/gtest.h"
9
10namespace media {
11
12static const int kSampleRate = 48000;
13
14static void VerifyBusWithOffset(AudioBus* bus,
15                                int offset,
16                                int frames,
17                                float start,
18                                float start_offset,
19                                float increment) {
20  for (int ch = 0; ch < bus->channels(); ++ch) {
21    const float v = start_offset + start + ch * bus->frames() * increment;
22    for (int i = offset; i < offset + frames; ++i) {
23      ASSERT_FLOAT_EQ(v + i * increment, bus->channel(ch)[i]) << "i=" << i
24                                                              << ", ch=" << ch;
25    }
26  }
27}
28
29static void VerifyBus(AudioBus* bus, int frames, float start, float increment) {
30  VerifyBusWithOffset(bus, 0, frames, start, 0, increment);
31}
32
33static void TrimRangeTest(SampleFormat sample_format) {
34  const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
35  const int channels = ChannelLayoutToChannelCount(channel_layout);
36  const int frames = kSampleRate / 10;
37  const base::TimeDelta timestamp = base::TimeDelta();
38  const base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
39  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<float>(sample_format,
40                                                             channel_layout,
41                                                             channels,
42                                                             kSampleRate,
43                                                             0,
44                                                             1,
45                                                             frames,
46                                                             timestamp);
47  EXPECT_EQ(frames, buffer->frame_count());
48  EXPECT_EQ(timestamp, buffer->timestamp());
49  EXPECT_EQ(duration, buffer->duration());
50
51  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
52
53  // Verify all frames before trimming.
54  buffer->ReadFrames(frames, 0, 0, bus.get());
55  VerifyBus(bus.get(), frames, 0, 1);
56
57  // Trim 10ms of frames from the middle of the buffer.
58  int trim_start = frames / 2;
59  const int trim_length = kSampleRate / 100;
60  const base::TimeDelta trim_duration = base::TimeDelta::FromMilliseconds(10);
61  buffer->TrimRange(trim_start, trim_start + trim_length);
62  EXPECT_EQ(frames - trim_length, buffer->frame_count());
63  EXPECT_EQ(timestamp, buffer->timestamp());
64  EXPECT_EQ(duration - trim_duration, buffer->duration());
65  bus->Zero();
66  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
67  VerifyBus(bus.get(), trim_start, 0, 1);
68  VerifyBusWithOffset(bus.get(),
69                      trim_start,
70                      buffer->frame_count() - trim_start,
71                      0,
72                      trim_length,
73                      1);
74
75  // Trim 10ms of frames from the start, which just adjusts the buffer's
76  // internal start offset.
77  buffer->TrimStart(trim_length);
78  trim_start -= trim_length;
79  EXPECT_EQ(frames - 2 * trim_length, buffer->frame_count());
80  EXPECT_EQ(timestamp + trim_duration, buffer->timestamp());
81  EXPECT_EQ(duration - 2 * trim_duration, buffer->duration());
82  bus->Zero();
83  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
84  VerifyBus(bus.get(), trim_start, trim_length, 1);
85  VerifyBusWithOffset(bus.get(),
86                      trim_start,
87                      buffer->frame_count() - trim_start,
88                      trim_length,
89                      trim_length,
90                      1);
91
92  // Trim 10ms of frames from the end, which just adjusts the buffer's frame
93  // count.
94  buffer->TrimEnd(trim_length);
95  EXPECT_EQ(frames - 3 * trim_length, buffer->frame_count());
96  EXPECT_EQ(timestamp + trim_duration, buffer->timestamp());
97  EXPECT_EQ(duration - 3 * trim_duration, buffer->duration());
98  bus->Zero();
99  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
100  VerifyBus(bus.get(), trim_start, trim_length, 1);
101  VerifyBusWithOffset(bus.get(),
102                      trim_start,
103                      buffer->frame_count() - trim_start,
104                      trim_length,
105                      trim_length,
106                      1);
107
108  // Trim another 10ms from the inner portion of the buffer.
109  buffer->TrimRange(trim_start, trim_start + trim_length);
110  EXPECT_EQ(frames - 4 * trim_length, buffer->frame_count());
111  EXPECT_EQ(timestamp + trim_duration, buffer->timestamp());
112  EXPECT_EQ(duration - 4 * trim_duration, buffer->duration());
113  bus->Zero();
114  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
115  VerifyBus(bus.get(), trim_start, trim_length, 1);
116  VerifyBusWithOffset(bus.get(),
117                      trim_start,
118                      buffer->frame_count() - trim_start,
119                      trim_length,
120                      trim_length * 2,
121                      1);
122
123  // Trim off the end using TrimRange() to ensure end index is exclusive.
124  buffer->TrimRange(buffer->frame_count() - trim_length, buffer->frame_count());
125  EXPECT_EQ(frames - 5 * trim_length, buffer->frame_count());
126  EXPECT_EQ(timestamp + trim_duration, buffer->timestamp());
127  EXPECT_EQ(duration - 5 * trim_duration, buffer->duration());
128  bus->Zero();
129  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
130  VerifyBus(bus.get(), trim_start, trim_length, 1);
131  VerifyBusWithOffset(bus.get(),
132                      trim_start,
133                      buffer->frame_count() - trim_start,
134                      trim_length,
135                      trim_length * 2,
136                      1);
137
138  // Trim off the start using TrimRange() to ensure start index is inclusive.
139  buffer->TrimRange(0, trim_length);
140  trim_start -= trim_length;
141  EXPECT_EQ(frames - 6 * trim_length, buffer->frame_count());
142  EXPECT_EQ(timestamp + trim_duration, buffer->timestamp());
143  EXPECT_EQ(duration - 6 * trim_duration, buffer->duration());
144  bus->Zero();
145  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
146  VerifyBus(bus.get(), trim_start, 2 * trim_length, 1);
147  VerifyBusWithOffset(bus.get(),
148                      trim_start,
149                      buffer->frame_count() - trim_start,
150                      trim_length * 2,
151                      trim_length * 2,
152                      1);
153}
154
155TEST(AudioBufferTest, CopyFrom) {
156  const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_MONO;
157  scoped_refptr<AudioBuffer> original_buffer =
158      MakeAudioBuffer<uint8>(kSampleFormatU8,
159                             kChannelLayout,
160                             ChannelLayoutToChannelCount(kChannelLayout),
161                             kSampleRate,
162                             1,
163                             1,
164                             kSampleRate / 100,
165                             base::TimeDelta());
166  scoped_refptr<AudioBuffer> new_buffer =
167      AudioBuffer::CopyFrom(kSampleFormatU8,
168                            original_buffer->channel_layout(),
169                            original_buffer->channel_count(),
170                            original_buffer->sample_rate(),
171                            original_buffer->frame_count(),
172                            &original_buffer->channel_data()[0],
173                            original_buffer->timestamp());
174  EXPECT_EQ(original_buffer->frame_count(), new_buffer->frame_count());
175  EXPECT_EQ(original_buffer->timestamp(), new_buffer->timestamp());
176  EXPECT_EQ(original_buffer->duration(), new_buffer->duration());
177  EXPECT_EQ(original_buffer->sample_rate(), new_buffer->sample_rate());
178  EXPECT_EQ(original_buffer->channel_count(), new_buffer->channel_count());
179  EXPECT_EQ(original_buffer->channel_layout(), new_buffer->channel_layout());
180  EXPECT_FALSE(original_buffer->end_of_stream());
181}
182
183TEST(AudioBufferTest, CreateEOSBuffer) {
184  scoped_refptr<AudioBuffer> buffer = AudioBuffer::CreateEOSBuffer();
185  EXPECT_TRUE(buffer->end_of_stream());
186}
187
188TEST(AudioBufferTest, FrameSize) {
189  const uint8 kTestData[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
190                              15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
191                              27, 28, 29, 30, 31 };
192  const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(1337);
193
194  const uint8* const data[] = { kTestData };
195  scoped_refptr<AudioBuffer> buffer =
196      AudioBuffer::CopyFrom(kSampleFormatU8,
197                            CHANNEL_LAYOUT_STEREO,
198                            2,
199                            kSampleRate,
200                            16,
201                            data,
202                            kTimestamp);
203  EXPECT_EQ(16, buffer->frame_count());  // 2 channels of 8-bit data
204
205  buffer = AudioBuffer::CopyFrom(kSampleFormatF32,
206                                 CHANNEL_LAYOUT_4_0,
207                                 4,
208                                 kSampleRate,
209                                 2,
210                                 data,
211                                 kTimestamp);
212  EXPECT_EQ(2, buffer->frame_count());  // now 4 channels of 32-bit data
213}
214
215TEST(AudioBufferTest, ReadU8) {
216  const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
217  const int channels = ChannelLayoutToChannelCount(channel_layout);
218  const int frames = 10;
219  const base::TimeDelta start_time;
220  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<uint8>(kSampleFormatU8,
221                                                             channel_layout,
222                                                             channels,
223                                                             kSampleRate,
224                                                             128,
225                                                             1,
226                                                             frames,
227                                                             start_time);
228  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
229  buffer->ReadFrames(frames, 0, 0, bus.get());
230  VerifyBus(bus.get(), frames, 0, 1.0f / 127.0f);
231
232  // Now read the same data one frame at a time.
233  bus->Zero();
234  for (int i = 0; i < frames; ++i)
235    buffer->ReadFrames(1, i, i, bus.get());
236  VerifyBus(bus.get(), frames, 0, 1.0f / 127.0f);
237}
238
239TEST(AudioBufferTest, ReadS16) {
240  const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
241  const int channels = ChannelLayoutToChannelCount(channel_layout);
242  const int frames = 10;
243  const base::TimeDelta start_time;
244  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<int16>(kSampleFormatS16,
245                                                             channel_layout,
246                                                             channels,
247                                                             kSampleRate,
248                                                             1,
249                                                             1,
250                                                             frames,
251                                                             start_time);
252  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
253  buffer->ReadFrames(frames, 0, 0, bus.get());
254  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
255
256  // Now read the same data one frame at a time.
257  bus->Zero();
258  for (int i = 0; i < frames; ++i)
259    buffer->ReadFrames(1, i, i, bus.get());
260  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
261}
262
263TEST(AudioBufferTest, ReadS32) {
264  const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
265  const int channels = ChannelLayoutToChannelCount(channel_layout);
266  const int frames = 20;
267  const base::TimeDelta start_time;
268  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<int32>(kSampleFormatS32,
269                                                             channel_layout,
270                                                             channels,
271                                                             kSampleRate,
272                                                             1,
273                                                             1,
274                                                             frames,
275                                                             start_time);
276  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
277  buffer->ReadFrames(frames, 0, 0, bus.get());
278  VerifyBus(bus.get(), frames, 1.0f / kint32max, 1.0f / kint32max);
279
280  // Read second 10 frames.
281  bus->Zero();
282  buffer->ReadFrames(10, 10, 0, bus.get());
283  VerifyBus(bus.get(), 10, 11.0f / kint32max, 1.0f / kint32max);
284}
285
286TEST(AudioBufferTest, ReadF32) {
287  const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
288  const int channels = ChannelLayoutToChannelCount(channel_layout);
289  const int frames = 20;
290  const base::TimeDelta start_time;
291  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<float>(kSampleFormatF32,
292                                                             channel_layout,
293                                                             channels,
294                                                             kSampleRate,
295                                                             1.0f,
296                                                             1.0f,
297                                                             frames,
298                                                             start_time);
299  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
300  buffer->ReadFrames(10, 0, 0, bus.get());
301  VerifyBus(bus.get(), 10, 1, 1);
302
303  // Read second 10 frames.
304  bus->Zero();
305  buffer->ReadFrames(10, 10, 0, bus.get());
306  VerifyBus(bus.get(), 10, 11, 1);
307}
308
309TEST(AudioBufferTest, ReadS16Planar) {
310  const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
311  const int channels = ChannelLayoutToChannelCount(channel_layout);
312  const int frames = 20;
313  const base::TimeDelta start_time;
314  scoped_refptr<AudioBuffer> buffer =
315      MakeAudioBuffer<int16>(kSampleFormatPlanarS16,
316                             channel_layout,
317                             channels,
318                             kSampleRate,
319                             1,
320                             1,
321                             frames,
322                             start_time);
323  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
324  buffer->ReadFrames(10, 0, 0, bus.get());
325  VerifyBus(bus.get(), 10, 1.0f / kint16max, 1.0f / kint16max);
326
327  // Read all the frames backwards, one by one. ch[0] should be 20, 19, ...
328  bus->Zero();
329  for (int i = frames - 1; i >= 0; --i)
330    buffer->ReadFrames(1, i, i, bus.get());
331  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
332
333  // Read 0 frames with different offsets. Existing data in AudioBus should be
334  // unchanged.
335  buffer->ReadFrames(0, 0, 0, bus.get());
336  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
337  buffer->ReadFrames(0, 0, 10, bus.get());
338  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
339  buffer->ReadFrames(0, 10, 0, bus.get());
340  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
341}
342
343TEST(AudioBufferTest, ReadF32Planar) {
344  const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
345  const int channels = ChannelLayoutToChannelCount(channel_layout);
346  const int frames = 100;
347  const base::TimeDelta start_time;
348  scoped_refptr<AudioBuffer> buffer =
349      MakeAudioBuffer<float>(kSampleFormatPlanarF32,
350                             channel_layout,
351                             channels,
352                             kSampleRate,
353                             1.0f,
354                             1.0f,
355                             frames,
356                             start_time);
357
358  // Read all 100 frames from the buffer. F32 is planar, so ch[0] should be 1,
359  // 2, 3, 4, ..., ch[1] should be 101, 102, 103, ..., and so on for all 4
360  // channels.
361  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
362  buffer->ReadFrames(frames, 0, 0, bus.get());
363  VerifyBus(bus.get(), frames, 1, 1);
364
365  // Now read 20 frames from the middle of the buffer.
366  bus->Zero();
367  buffer->ReadFrames(20, 50, 0, bus.get());
368  VerifyBus(bus.get(), 20, 51, 1);
369}
370
371TEST(AudioBufferTest, EmptyBuffer) {
372  const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
373  const int channels = ChannelLayoutToChannelCount(channel_layout);
374  const int frames = kSampleRate / 100;
375  const base::TimeDelta start_time;
376  scoped_refptr<AudioBuffer> buffer = AudioBuffer::CreateEmptyBuffer(
377      channel_layout, channels, kSampleRate, frames, start_time);
378  EXPECT_EQ(frames, buffer->frame_count());
379  EXPECT_EQ(start_time, buffer->timestamp());
380  EXPECT_EQ(base::TimeDelta::FromMilliseconds(10), buffer->duration());
381  EXPECT_FALSE(buffer->end_of_stream());
382
383  // Read all 100 frames from the buffer. All data should be 0.
384  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
385  buffer->ReadFrames(frames, 0, 0, bus.get());
386  VerifyBus(bus.get(), frames, 0, 0);
387}
388
389TEST(AudioBufferTest, Trim) {
390  const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
391  const int channels = ChannelLayoutToChannelCount(channel_layout);
392  const int frames = kSampleRate / 10;
393  const base::TimeDelta start_time;
394  const base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
395  scoped_refptr<AudioBuffer> buffer =
396      MakeAudioBuffer<float>(kSampleFormatPlanarF32,
397                             channel_layout,
398                             channels,
399                             kSampleRate,
400                             0.0f,
401                             1.0f,
402                             frames,
403                             start_time);
404  EXPECT_EQ(frames, buffer->frame_count());
405  EXPECT_EQ(start_time, buffer->timestamp());
406  EXPECT_EQ(duration, buffer->duration());
407
408  const int ten_ms_of_frames = kSampleRate / 100;
409  const base::TimeDelta ten_ms = base::TimeDelta::FromMilliseconds(10);
410
411  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
412  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
413  VerifyBus(bus.get(), buffer->frame_count(), 0.0f, 1.0f);
414
415  // Trim off 10ms of frames from the start.
416  buffer->TrimStart(ten_ms_of_frames);
417  EXPECT_EQ(start_time + ten_ms, buffer->timestamp());
418  EXPECT_EQ(frames - ten_ms_of_frames, buffer->frame_count());
419  EXPECT_EQ(duration - ten_ms, buffer->duration());
420  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
421  VerifyBus(bus.get(), buffer->frame_count(), ten_ms_of_frames, 1.0f);
422
423  // Trim off 10ms of frames from the end.
424  buffer->TrimEnd(ten_ms_of_frames);
425  EXPECT_EQ(start_time + ten_ms, buffer->timestamp());
426  EXPECT_EQ(frames - 2 * ten_ms_of_frames, buffer->frame_count());
427  EXPECT_EQ(duration - 2 * ten_ms, buffer->duration());
428  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
429  VerifyBus(bus.get(), buffer->frame_count(), ten_ms_of_frames, 1.0f);
430
431  // Trim off 40ms more from the start.
432  buffer->TrimStart(4 * ten_ms_of_frames);
433  EXPECT_EQ(start_time + 5 * ten_ms, buffer->timestamp());
434  EXPECT_EQ(frames - 6 * ten_ms_of_frames, buffer->frame_count());
435  EXPECT_EQ(duration - 6 * ten_ms, buffer->duration());
436  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
437  VerifyBus(bus.get(), buffer->frame_count(), 5 * ten_ms_of_frames, 1.0f);
438
439  // Trim off the final 40ms from the end.
440  buffer->TrimEnd(4 * ten_ms_of_frames);
441  EXPECT_EQ(0, buffer->frame_count());
442  EXPECT_EQ(start_time + 5 * ten_ms, buffer->timestamp());
443  EXPECT_EQ(base::TimeDelta(), buffer->duration());
444}
445
446TEST(AudioBufferTest, TrimRangePlanar) {
447  TrimRangeTest(kSampleFormatPlanarF32);
448}
449
450TEST(AudioBufferTest, TrimRangeInterleaved) {
451  TrimRangeTest(kSampleFormatF32);
452}
453
454}  // namespace media
455