123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- // Copyright 2018 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 "services/audio/delay_buffer.h"
- #include <algorithm>
- #include "media/base/audio_bus.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace audio {
- namespace {
- constexpr int kChannels = 1;
- constexpr int kMaxFrames = 32;
- #define EXPECT_BUS_VALUES_EQ(bus, begin, end, value) \
- { \
- const auto IsValue = [](float x) { return x == (value); }; \
- EXPECT_TRUE(std::all_of((bus)->channel(0) + (begin), \
- (bus)->channel(0) + (end) - (begin), IsValue)); \
- }
- TEST(DelayBufferTest, RecordsAMaximumNumberOfFrames) {
- DelayBuffer buffer(kMaxFrames);
- ASSERT_EQ(buffer.GetBeginPosition(), buffer.GetEndPosition());
- constexpr int frames_per_bus = kMaxFrames / 4;
- const auto bus = media::AudioBus::Create(kChannels, frames_per_bus);
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 1.0);
- // Fill the buffer.
- DelayBuffer::FrameTicks position = 0;
- for (int i = 0; i < 4; ++i) {
- buffer.Write(position, *bus, 1.0);
- position += frames_per_bus;
- EXPECT_EQ(0, buffer.GetBeginPosition());
- EXPECT_EQ(position, buffer.GetEndPosition());
- }
- // Writing just one more bus should cause the leading frames to be dropped.
- buffer.Write(position, *bus, 1.0);
- position += frames_per_bus;
- EXPECT_EQ(position - kMaxFrames, buffer.GetBeginPosition());
- EXPECT_EQ(position, buffer.GetEndPosition());
- // Now, simulate a gap in the recording by recording the next bus late.
- position += frames_per_bus * 2;
- buffer.Write(position, *bus, 1.0);
- position += frames_per_bus;
- EXPECT_EQ(position - kMaxFrames, buffer.GetBeginPosition());
- EXPECT_EQ(position, buffer.GetEndPosition());
- }
- TEST(DelayBufferTest, ReadsSilenceIfNothingWasRecorded) {
- DelayBuffer buffer(kMaxFrames);
- ASSERT_EQ(buffer.GetBeginPosition(), buffer.GetEndPosition());
- DelayBuffer::FrameTicks position = 0;
- constexpr int frames_per_bus = kMaxFrames / 4;
- const auto bus = media::AudioBus::Create(kChannels, frames_per_bus);
- for (int i = 0; i < 10; ++i) {
- // Set data in the bus to confirm it is all going to be overwritten.
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 1.0);
- buffer.Read(position, frames_per_bus, bus.get());
- EXPECT_EQ(buffer.GetBeginPosition(), buffer.GetEndPosition());
- EXPECT_BUS_VALUES_EQ(bus, 0, frames_per_bus, 0.0);
- position += frames_per_bus;
- }
- }
- TEST(DelayBufferTest, ReadsSilenceIfOutsideRecordedRange) {
- DelayBuffer buffer(kMaxFrames);
- ASSERT_EQ(buffer.GetBeginPosition(), buffer.GetEndPosition());
- constexpr int frames_per_bus = kMaxFrames / 4;
- const auto bus = media::AudioBus::Create(kChannels, frames_per_bus);
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 1.0);
- // Fill the buffer.
- DelayBuffer::FrameTicks position = 0;
- for (int i = 0; i < 4; ++i) {
- buffer.Write(position, *bus, 1.0);
- position += frames_per_bus;
- }
- EXPECT_EQ(0, buffer.GetBeginPosition());
- EXPECT_EQ(position, buffer.GetEndPosition());
- // Read before the begin position and expect to get silence.
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
- buffer.Read(-kMaxFrames, frames_per_bus, bus.get());
- EXPECT_BUS_VALUES_EQ(bus, 0, frames_per_bus, 0.0);
- // Read at a position one before the begin position. Expect the first sample
- // to be 0.0, and the rest 1.0.
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
- buffer.Read(buffer.GetBeginPosition() - 1, frames_per_bus, bus.get());
- EXPECT_EQ(0.0, bus->channel(0)[0]);
- EXPECT_BUS_VALUES_EQ(bus, 1, frames_per_bus - 1, 1.0);
- // Read at a position where the last sample should be 0.0 and the rest 1.0.
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
- buffer.Read(buffer.GetEndPosition() - frames_per_bus + 1, frames_per_bus,
- bus.get());
- EXPECT_BUS_VALUES_EQ(bus, 0, frames_per_bus - 1, 1.0);
- EXPECT_EQ(0.0, bus->channel(0)[frames_per_bus - 1]);
- // Read after the end position and expect to get silence.
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
- buffer.Read(kMaxFrames, frames_per_bus, bus.get());
- EXPECT_BUS_VALUES_EQ(bus, 0, frames_per_bus, 0.0);
- }
- TEST(DelayBufferTest, ReadsGapsInRecording) {
- DelayBuffer buffer(kMaxFrames);
- ASSERT_EQ(buffer.GetBeginPosition(), buffer.GetEndPosition());
- constexpr int frames_per_bus = kMaxFrames / 4;
- const auto bus = media::AudioBus::Create(kChannels, frames_per_bus);
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 1.0);
- // Fill the buffer, but with a gap in the third quarter of it.
- DelayBuffer::FrameTicks record_position = 0;
- for (int i = 0; i < 4; ++i) {
- if (i != 2) {
- buffer.Write(record_position, *bus, 1.0);
- }
- record_position += frames_per_bus;
- }
- EXPECT_EQ(0, buffer.GetBeginPosition());
- EXPECT_EQ(record_position, buffer.GetEndPosition());
- // Read through the whole range, but offset by one frame early. Confirm the
- // silence gap appears in the right place.
- DelayBuffer::FrameTicks read_position = -1;
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
- buffer.Read(read_position, frames_per_bus, bus.get());
- read_position += frames_per_bus;
- EXPECT_EQ(0.0, bus->channel(0)[0]);
- EXPECT_BUS_VALUES_EQ(bus, 1, frames_per_bus - 1, 1.0);
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
- buffer.Read(read_position, frames_per_bus, bus.get());
- read_position += frames_per_bus;
- EXPECT_BUS_VALUES_EQ(bus, 0, frames_per_bus, 1.0);
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
- buffer.Read(read_position, frames_per_bus, bus.get());
- read_position += frames_per_bus;
- EXPECT_EQ(1.0, bus->channel(0)[0]);
- // The gap begins.
- EXPECT_BUS_VALUES_EQ(bus, 1, frames_per_bus - 1, 0.0);
- std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
- buffer.Read(read_position, frames_per_bus, bus.get());
- read_position += frames_per_bus;
- EXPECT_EQ(0.0, bus->channel(0)[0]);
- // The gap ends.
- EXPECT_BUS_VALUES_EQ(bus, 1, frames_per_bus - 1, 1.0);
- }
- } // namespace
- } // namespace audio
|