// 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 static scoped_refptr MakeTestBuffer(SampleFormat format, ChannelLayout channel_layout, T start, T step, int frames) { return MakeAudioBuffer(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(kSampleFormatU8, channel_layout, 10, 1, 8)); EXPECT_EQ(8, buffer.frames()); buffer.Clear(); EXPECT_EQ(0, buffer.frames()); buffer.Append( MakeTestBuffer(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(kSampleFormatU8, channel_layout, 10, 1, 8)); EXPECT_EQ(8, buffer.frames()); buffer.Append( MakeTestBuffer(kSampleFormatU8, channel_layout, 10, 1, 8)); EXPECT_EQ(16, buffer.frames()); buffer.Append( MakeTestBuffer(kSampleFormatU8, channel_layout, 10, 1, 8)); EXPECT_EQ(24, buffer.frames()); buffer.Append( MakeTestBuffer(kSampleFormatU8, channel_layout, 10, 1, 8)); EXPECT_EQ(32, buffer.frames()); buffer.Append( MakeTestBuffer(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 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( 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( kSampleFormatF32, channel_layout, 20.0f, 1.0f, 8)); EXPECT_EQ(12, buffer.frames()); buffer.Append(MakeTestBuffer( 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( kSampleFormatF32, channel_layout, 40.0f, 1.0f, 8)); EXPECT_EQ(8, buffer.frames()); buffer.Append(MakeTestBuffer( 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( 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(kSampleFormatF32, channel_layout, 1.0f, 1.0f, 6)); buffer.Append( MakeTestBuffer(kSampleFormatF32, channel_layout, 13.0f, 1.0f, 10)); buffer.Append( MakeTestBuffer(kSampleFormatF32, channel_layout, 33.0f, 1.0f, 60)); EXPECT_EQ(76, buffer.frames()); // Read 3 frames from the buffer. scoped_ptr 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(kSampleFormatU8, channel_layout, 128, 1, frames)); // Read all 4 frames from the buffer. scoped_ptr 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(kSampleFormatS16, channel_layout, 1, 1, 4)); buffer.Append( MakeTestBuffer(kSampleFormatS16, channel_layout, 9, 1, 20)); EXPECT_EQ(24, buffer.frames()); // Read 6 frames from the buffer. const int frames = 6; scoped_ptr 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(kSampleFormatS32, channel_layout, 1, 1, 4)); buffer.Append( MakeTestBuffer(kSampleFormatS32, channel_layout, 9, 1, 20)); EXPECT_EQ(24, buffer.frames()); // Read 6 frames from the buffer. scoped_ptr 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( kSampleFormatPlanarF32, channel_layout, 1.0f, 1.0f, 4)); buffer.Append(MakeTestBuffer( kSampleFormatPlanarF32, channel_layout, 50.0f, 1.0f, 10)); EXPECT_EQ(14, buffer.frames()); // Read 6 frames from the buffer. scoped_ptr 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(kSampleFormatPlanarS16, channel_layout, 1, 1, 4)); buffer.Append( MakeTestBuffer(kSampleFormatPlanarS16, channel_layout, 5, 1, 20)); EXPECT_EQ(24, buffer.frames()); // Read 6 frames from the buffer. scoped_ptr 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(kSampleFormatF32, channel_layout, 0.0f, 1.0f, 6)); buffer.Append(MakeTestBuffer( kSampleFormatF32, channel_layout, 6.0f * channels, 1.0f, 10)); buffer.Append(MakeTestBuffer( kSampleFormatF32, channel_layout, 16.0f * channels, 1.0f, 60)); EXPECT_EQ(76, buffer.frames()); // Read 3 frames from the buffer. scoped_ptr 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( kSampleFormatF32, channel_layout, 0.0f, 1.0f, frames)); EXPECT_EQ(frames, buffer.frames()); // Peek at the first 30 frames. scoped_ptr 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 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())); } } // namespace media