blob: dfb2098e1aa29bcec87bec6bf1705e5c16b192a0 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "media/base/audio_buffer.h"
#include "media/base/audio_buffer_queue.h"
#include "media/base/audio_bus.h"
#include "media/base/buffers.h"
#include "media/base/test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
const int kSampleRate = 44100;
static void VerifyBus(AudioBus* bus,
int offset,
int frames,
int buffer_size,
float start,
float increment) {
for (int ch = 0; ch < bus->channels(); ++ch) {
const float v = start + ch * buffer_size * increment;
for (int i = offset; i < offset + frames; ++i) {
ASSERT_FLOAT_EQ(v + (i - offset) * increment, bus->channel(ch)[i])
<< "i=" << i << ", ch=" << ch;
}
}
}
template <typename T>
static scoped_refptr<AudioBuffer> MakeTestBuffer(SampleFormat format,
ChannelLayout channel_layout,
T start,
T step,
int frames) {
return MakeAudioBuffer<T>(format,
channel_layout,
ChannelLayoutToChannelCount(channel_layout),
kSampleRate,
start,
step,
frames,
kNoTimestamp());
}
TEST(AudioBufferQueueTest, AppendAndClear) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO;
AudioBufferQueue buffer;
EXPECT_EQ(0, buffer.frames());
buffer.Append(
MakeTestBuffer<uint8>(kSampleFormatU8, channel_layout, 10, 1, 8));
EXPECT_EQ(8, buffer.frames());
buffer.Clear();
EXPECT_EQ(0, buffer.frames());
buffer.Append(
MakeTestBuffer<uint8>(kSampleFormatU8, channel_layout, 20, 1, 8));
EXPECT_EQ(8, buffer.frames());
}
TEST(AudioBufferQueueTest, MultipleAppend) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO;
AudioBufferQueue buffer;
buffer.Append(
MakeTestBuffer<uint8>(kSampleFormatU8, channel_layout, 10, 1, 8));
EXPECT_EQ(8, buffer.frames());
buffer.Append(
MakeTestBuffer<uint8>(kSampleFormatU8, channel_layout, 10, 1, 8));
EXPECT_EQ(16, buffer.frames());
buffer.Append(
MakeTestBuffer<uint8>(kSampleFormatU8, channel_layout, 10, 1, 8));
EXPECT_EQ(24, buffer.frames());
buffer.Append(
MakeTestBuffer<uint8>(kSampleFormatU8, channel_layout, 10, 1, 8));
EXPECT_EQ(32, buffer.frames());
buffer.Append(
MakeTestBuffer<uint8>(kSampleFormatU8, channel_layout, 10, 1, 8));
EXPECT_EQ(40, buffer.frames());
}
TEST(AudioBufferQueueTest, IteratorCheck) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO;
const int channels = ChannelLayoutToChannelCount(channel_layout);
AudioBufferQueue buffer;
scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
// Append 40 frames in 5 buffers. Intersperse ReadFrames() to make the
// iterator is pointing to the correct position.
buffer.Append(MakeTestBuffer<float>(
kSampleFormatF32, channel_layout, 10.0f, 1.0f, 8));
EXPECT_EQ(8, buffer.frames());
EXPECT_EQ(4, buffer.ReadFrames(4, 0, bus.get()));
EXPECT_EQ(4, buffer.frames());
VerifyBus(bus.get(), 0, 4, bus->frames(), 10, 1);
buffer.Append(MakeTestBuffer<float>(
kSampleFormatF32, channel_layout, 20.0f, 1.0f, 8));
EXPECT_EQ(12, buffer.frames());
buffer.Append(MakeTestBuffer<float>(
kSampleFormatF32, channel_layout, 30.0f, 1.0f, 8));
EXPECT_EQ(20, buffer.frames());
buffer.SeekFrames(16);
EXPECT_EQ(4, buffer.ReadFrames(4, 0, bus.get()));
EXPECT_EQ(0, buffer.frames());
VerifyBus(bus.get(), 0, 4, bus->frames(), 34, 1);
buffer.Append(MakeTestBuffer<float>(
kSampleFormatF32, channel_layout, 40.0f, 1.0f, 8));
EXPECT_EQ(8, buffer.frames());
buffer.Append(MakeTestBuffer<float>(
kSampleFormatF32, channel_layout, 50.0f, 1.0f, 8));
EXPECT_EQ(16, buffer.frames());
EXPECT_EQ(4, buffer.ReadFrames(4, 0, bus.get()));
VerifyBus(bus.get(), 0, 4, bus->frames(), 40, 1);
// Read off the end of the buffer.
EXPECT_EQ(12, buffer.frames());
buffer.SeekFrames(8);
EXPECT_EQ(4, buffer.ReadFrames(100, 0, bus.get()));
VerifyBus(bus.get(), 0, 4, bus->frames(), 54, 1);
}
TEST(AudioBufferQueueTest, Seek) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
AudioBufferQueue buffer;
// Add 6 frames of data.
buffer.Append(MakeTestBuffer<float>(
kSampleFormatF32, channel_layout, 1.0f, 1.0f, 6));
EXPECT_EQ(6, buffer.frames());
// Seek past 2 frames.
buffer.SeekFrames(2);
EXPECT_EQ(4, buffer.frames());
// Seek to end of data.
buffer.SeekFrames(4);
EXPECT_EQ(0, buffer.frames());
// At end, seek now fails unless 0 specified.
buffer.SeekFrames(0);
}
TEST(AudioBufferQueueTest, ReadF32) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
const int channels = ChannelLayoutToChannelCount(channel_layout);
AudioBufferQueue buffer;
// Add 76 frames of data.
buffer.Append(
MakeTestBuffer<float>(kSampleFormatF32, channel_layout, 1.0f, 1.0f, 6));
buffer.Append(
MakeTestBuffer<float>(kSampleFormatF32, channel_layout, 13.0f, 1.0f, 10));
buffer.Append(
MakeTestBuffer<float>(kSampleFormatF32, channel_layout, 33.0f, 1.0f, 60));
EXPECT_EQ(76, buffer.frames());
// Read 3 frames from the buffer.
scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
EXPECT_EQ(3, buffer.ReadFrames(3, 0, bus.get()));
EXPECT_EQ(73, buffer.frames());
VerifyBus(bus.get(), 0, 3, 6, 1, 1);
// Now read 5 frames, which will span buffers. Append the data into AudioBus.
EXPECT_EQ(5, buffer.ReadFrames(5, 3, bus.get()));
EXPECT_EQ(68, buffer.frames());
VerifyBus(bus.get(), 0, 6, 6, 1, 1);
VerifyBus(bus.get(), 6, 2, 10, 13, 1);
// Now skip into the third buffer.
buffer.SeekFrames(20);
EXPECT_EQ(48, buffer.frames());
// Now read 2 frames, which are in the third buffer.
EXPECT_EQ(2, buffer.ReadFrames(2, 0, bus.get()));
VerifyBus(bus.get(), 0, 2, 60, 45, 1);
}
TEST(AudioBufferQueueTest, ReadU8) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
const int channels = ChannelLayoutToChannelCount(channel_layout);
const int frames = 4;
AudioBufferQueue buffer;
// Add 4 frames of data.
buffer.Append(
MakeTestBuffer<uint8>(kSampleFormatU8, channel_layout, 128, 1, frames));
// Read all 4 frames from the buffer.
scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
EXPECT_EQ(frames, buffer.ReadFrames(frames, 0, bus.get()));
EXPECT_EQ(0, buffer.frames());
VerifyBus(bus.get(), 0, frames, bus->frames(), 0, 1.0f / 127.0f);
}
TEST(AudioBufferQueueTest, ReadS16) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
const int channels = ChannelLayoutToChannelCount(channel_layout);
AudioBufferQueue buffer;
// Add 24 frames of data.
buffer.Append(
MakeTestBuffer<int16>(kSampleFormatS16, channel_layout, 1, 1, 4));
buffer.Append(
MakeTestBuffer<int16>(kSampleFormatS16, channel_layout, 9, 1, 20));
EXPECT_EQ(24, buffer.frames());
// Read 6 frames from the buffer.
const int frames = 6;
scoped_ptr<AudioBus> bus = AudioBus::Create(channels, buffer.frames());
EXPECT_EQ(frames, buffer.ReadFrames(frames, 0, bus.get()));
EXPECT_EQ(18, buffer.frames());
VerifyBus(bus.get(), 0, 4, 4, 1.0f / kint16max, 1.0f / kint16max);
VerifyBus(bus.get(), 4, 2, 20, 9.0f / kint16max, 1.0f / kint16max);
}
TEST(AudioBufferQueueTest, ReadS32) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
const int channels = ChannelLayoutToChannelCount(channel_layout);
AudioBufferQueue buffer;
// Add 24 frames of data.
buffer.Append(
MakeTestBuffer<int32>(kSampleFormatS32, channel_layout, 1, 1, 4));
buffer.Append(
MakeTestBuffer<int32>(kSampleFormatS32, channel_layout, 9, 1, 20));
EXPECT_EQ(24, buffer.frames());
// Read 6 frames from the buffer.
scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
EXPECT_EQ(6, buffer.ReadFrames(6, 0, bus.get()));
EXPECT_EQ(18, buffer.frames());
VerifyBus(bus.get(), 0, 4, 4, 1.0f / kint32max, 1.0f / kint32max);
VerifyBus(bus.get(), 4, 2, 20, 9.0f / kint32max, 1.0f / kint32max);
// Read the next 2 frames.
EXPECT_EQ(2, buffer.ReadFrames(2, 0, bus.get()));
EXPECT_EQ(16, buffer.frames());
VerifyBus(bus.get(), 0, 2, 20, 11.0f / kint32max, 1.0f / kint32max);
}
TEST(AudioBufferQueueTest, ReadF32Planar) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
const int channels = ChannelLayoutToChannelCount(channel_layout);
AudioBufferQueue buffer;
// Add 14 frames of data.
buffer.Append(MakeTestBuffer<float>(
kSampleFormatPlanarF32, channel_layout, 1.0f, 1.0f, 4));
buffer.Append(MakeTestBuffer<float>(
kSampleFormatPlanarF32, channel_layout, 50.0f, 1.0f, 10));
EXPECT_EQ(14, buffer.frames());
// Read 6 frames from the buffer.
scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
EXPECT_EQ(6, buffer.ReadFrames(6, 0, bus.get()));
EXPECT_EQ(8, buffer.frames());
VerifyBus(bus.get(), 0, 4, 4, 1, 1);
VerifyBus(bus.get(), 4, 2, 10, 50, 1);
}
TEST(AudioBufferQueueTest, ReadS16Planar) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
const int channels = ChannelLayoutToChannelCount(channel_layout);
AudioBufferQueue buffer;
// Add 24 frames of data.
buffer.Append(
MakeTestBuffer<int16>(kSampleFormatPlanarS16, channel_layout, 1, 1, 4));
buffer.Append(
MakeTestBuffer<int16>(kSampleFormatPlanarS16, channel_layout, 5, 1, 20));
EXPECT_EQ(24, buffer.frames());
// Read 6 frames from the buffer.
scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
EXPECT_EQ(6, buffer.ReadFrames(6, 0, bus.get()));
EXPECT_EQ(18, buffer.frames());
VerifyBus(bus.get(), 0, 4, 4, 1.0f / kint16max, 1.0f / kint16max);
VerifyBus(bus.get(), 4, 2, 20, 5.0f / kint16max, 1.0f / kint16max);
}
TEST(AudioBufferQueueTest, ReadManyChannels) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_OCTAGONAL;
const int channels = ChannelLayoutToChannelCount(channel_layout);
AudioBufferQueue buffer;
// Add 76 frames of data.
buffer.Append(
MakeTestBuffer<float>(kSampleFormatF32, channel_layout, 0.0f, 1.0f, 6));
buffer.Append(MakeTestBuffer<float>(
kSampleFormatF32, channel_layout, 6.0f * channels, 1.0f, 10));
buffer.Append(MakeTestBuffer<float>(
kSampleFormatF32, channel_layout, 16.0f * channels, 1.0f, 60));
EXPECT_EQ(76, buffer.frames());
// Read 3 frames from the buffer.
scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
EXPECT_EQ(30, buffer.ReadFrames(30, 0, bus.get()));
EXPECT_EQ(46, buffer.frames());
VerifyBus(bus.get(), 0, 6, 6, 0, 1);
VerifyBus(bus.get(), 6, 10, 10, 6 * channels, 1);
VerifyBus(bus.get(), 16, 14, 60, 16 * channels, 1);
}
TEST(AudioBufferQueueTest, Peek) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
const int channels = ChannelLayoutToChannelCount(channel_layout);
AudioBufferQueue buffer;
// Add 60 frames of data.
const int frames = 60;
buffer.Append(MakeTestBuffer<float>(
kSampleFormatF32, channel_layout, 0.0f, 1.0f, frames));
EXPECT_EQ(frames, buffer.frames());
// Peek at the first 30 frames.
scoped_ptr<AudioBus> bus1 = AudioBus::Create(channels, frames);
EXPECT_EQ(frames, buffer.frames());
EXPECT_EQ(frames, buffer.PeekFrames(60, 0, 0, bus1.get()));
EXPECT_EQ(30, buffer.PeekFrames(30, 0, 0, bus1.get()));
EXPECT_EQ(frames, buffer.frames());
VerifyBus(bus1.get(), 0, 30, bus1->frames(), 0, 1);
// Now read the next 30 frames (which should be the same as those peeked at).
scoped_ptr<AudioBus> bus2 = AudioBus::Create(channels, frames);
EXPECT_EQ(30, buffer.ReadFrames(30, 0, bus2.get()));
VerifyBus(bus2.get(), 0, 30, bus2->frames(), 0, 1);
// Peek 10 frames forward
bus1->Zero();
EXPECT_EQ(5, buffer.PeekFrames(5, 10, 0, bus1.get()));
VerifyBus(bus1.get(), 0, 5, bus1->frames(), 40, 1);
// Peek to the end of the buffer.
EXPECT_EQ(30, buffer.frames());
EXPECT_EQ(30, buffer.PeekFrames(60, 0, 0, bus1.get()));
EXPECT_EQ(30, buffer.PeekFrames(30, 0, 0, bus1.get()));
}
TEST(AudioBufferQueueTest, Time) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
const int channels = ChannelLayoutToChannelCount(channel_layout);
const base::TimeDelta start_time1;
const base::TimeDelta start_time2 = base::TimeDelta::FromSeconds(30);
AudioBufferQueue buffer;
scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
scoped_refptr<AudioBuffer> audio_buffer =
MakeAudioBuffer<int16>(kSampleFormatS16,
channel_layout,
channels,
kSampleRate,
1,
1,
10,
start_time1);
// Add two buffers (second one added later):
// first: start=0s, duration=10s
// second: start=30s, duration=10s
buffer.Append(audio_buffer);
EXPECT_EQ(10, buffer.frames());
// Check starting time.
EXPECT_EQ(start_time1, buffer.current_time());
// Read 2 frames, should be 2s in (since duration is 1s per sample).
int frames_read = 2;
EXPECT_EQ(frames_read, buffer.ReadFrames(frames_read, 0, bus.get()));
EXPECT_EQ(
start_time1 +
frames_read * audio_buffer->duration() / audio_buffer->frame_count(),
buffer.current_time());
// Skip 2 frames.
buffer.SeekFrames(2);
frames_read += 2;
EXPECT_EQ(
start_time1 +
frames_read * audio_buffer->duration() / audio_buffer->frame_count(),
buffer.current_time());
// Add second buffer for more data.
buffer.Append(MakeAudioBuffer<int16>(kSampleFormatS16,
channel_layout,
channels,
kSampleRate,
1,
1,
10,
start_time2));
EXPECT_EQ(16, buffer.frames());
// Read until almost the end of buffer1.
frames_read += 5;
EXPECT_EQ(5, buffer.ReadFrames(5, 0, bus.get()));
EXPECT_EQ(
start_time1 +
frames_read * audio_buffer->duration() / audio_buffer->frame_count(),
buffer.current_time());
// Read 1 value, so time moved to buffer2.
EXPECT_EQ(1, buffer.ReadFrames(1, 0, bus.get()));
EXPECT_EQ(start_time2, buffer.current_time());
// Read all 10 frames in buffer2, timestamp should be last time from buffer2.
frames_read = 10;
EXPECT_EQ(10, buffer.ReadFrames(10, 0, bus.get()));
const base::TimeDelta expected_current_time =
start_time2 +
frames_read * audio_buffer->duration() / audio_buffer->frame_count();
EXPECT_EQ(expected_current_time, buffer.current_time());
// Try to read more frames (which don't exist), timestamp should remain.
EXPECT_EQ(0, buffer.ReadFrames(5, 0, bus.get()));
EXPECT_EQ(expected_current_time, buffer.current_time());
}
TEST(AudioBufferQueueTest, NoTime) {
const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
const int channels = ChannelLayoutToChannelCount(channel_layout);
const base::TimeDelta kNoTime = kNoTimestamp();
AudioBufferQueue buffer;
scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
// Add two buffers with no timestamps. Time should always be unknown.
buffer.Append(
MakeTestBuffer<int16>(kSampleFormatS16, channel_layout, 1, 1, 10));
buffer.Append(
MakeTestBuffer<int16>(kSampleFormatS16, channel_layout, 1, 1, 10));
EXPECT_EQ(20, buffer.frames());
// Check starting time.
EXPECT_EQ(kNoTime, buffer.current_time());
// Read 2 frames.
EXPECT_EQ(2, buffer.ReadFrames(2, 0, bus.get()));
EXPECT_EQ(kNoTime, buffer.current_time());
// Skip 2 frames.
buffer.SeekFrames(2);
EXPECT_EQ(kNoTime, buffer.current_time());
// Read until almost the end of buffer1.
EXPECT_EQ(5, buffer.ReadFrames(5, 0, bus.get()));
EXPECT_EQ(kNoTime, buffer.current_time());
// Read 1 value, so time moved to buffer2.
EXPECT_EQ(1, buffer.ReadFrames(1, 0, bus.get()));
EXPECT_EQ(kNoTime, buffer.current_time());
// Read all 10 frames in buffer2.
EXPECT_EQ(10, buffer.ReadFrames(10, 0, bus.get()));
EXPECT_EQ(kNoTime, buffer.current_time());
// Try to read more frames (which don't exist), timestamp should remain.
EXPECT_EQ(0, buffer.ReadFrames(5, 0, bus.get()));
EXPECT_EQ(kNoTime, buffer.current_time());
}
} // namespace media