1 // Copyright 2018 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 "services/audio/delay_buffer.h"
6 
7 #include <algorithm>
8 
9 #include "media/base/audio_bus.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 
12 namespace audio {
13 namespace {
14 
15 constexpr int kChannels = 1;
16 constexpr int kMaxFrames = 32;
17 
18 #define EXPECT_BUS_VALUES_EQ(bus, begin, end, value)                        \
19   {                                                                         \
20     const auto IsValue = [](float x) { return x == (value); };              \
21     EXPECT_TRUE(std::all_of((bus)->channel(0) + (begin),                    \
22                             (bus)->channel(0) + (end) - (begin), IsValue)); \
23   }
24 
TEST(DelayBufferTest,RecordsAMaximumNumberOfFrames)25 TEST(DelayBufferTest, RecordsAMaximumNumberOfFrames) {
26   DelayBuffer buffer(kMaxFrames);
27   ASSERT_EQ(buffer.GetBeginPosition(), buffer.GetEndPosition());
28 
29   constexpr int frames_per_bus = kMaxFrames / 4;
30   const auto bus = media::AudioBus::Create(kChannels, frames_per_bus);
31   std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 1.0);
32 
33   // Fill the buffer.
34   DelayBuffer::FrameTicks position = 0;
35   for (int i = 0; i < 4; ++i) {
36     buffer.Write(position, *bus, 1.0);
37     position += frames_per_bus;
38     EXPECT_EQ(0, buffer.GetBeginPosition());
39     EXPECT_EQ(position, buffer.GetEndPosition());
40   }
41 
42   // Writing just one more bus should cause the leading frames to be dropped.
43   buffer.Write(position, *bus, 1.0);
44   position += frames_per_bus;
45   EXPECT_EQ(position - kMaxFrames, buffer.GetBeginPosition());
46   EXPECT_EQ(position, buffer.GetEndPosition());
47 
48   // Now, simulate a gap in the recording by recording the next bus late.
49   position += frames_per_bus * 2;
50   buffer.Write(position, *bus, 1.0);
51   position += frames_per_bus;
52   EXPECT_EQ(position - kMaxFrames, buffer.GetBeginPosition());
53   EXPECT_EQ(position, buffer.GetEndPosition());
54 }
55 
TEST(DelayBufferTest,ReadsSilenceIfNothingWasRecorded)56 TEST(DelayBufferTest, ReadsSilenceIfNothingWasRecorded) {
57   DelayBuffer buffer(kMaxFrames);
58   ASSERT_EQ(buffer.GetBeginPosition(), buffer.GetEndPosition());
59 
60   DelayBuffer::FrameTicks position = 0;
61   constexpr int frames_per_bus = kMaxFrames / 4;
62   const auto bus = media::AudioBus::Create(kChannels, frames_per_bus);
63 
64   for (int i = 0; i < 10; ++i) {
65     // Set data in the bus to confirm it is all going to be overwritten.
66     std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 1.0);
67 
68     buffer.Read(position, frames_per_bus, bus.get());
69     EXPECT_EQ(buffer.GetBeginPosition(), buffer.GetEndPosition());
70     EXPECT_BUS_VALUES_EQ(bus, 0, frames_per_bus, 0.0);
71 
72     position += frames_per_bus;
73   }
74 }
75 
TEST(DelayBufferTest,ReadsSilenceIfOutsideRecordedRange)76 TEST(DelayBufferTest, ReadsSilenceIfOutsideRecordedRange) {
77   DelayBuffer buffer(kMaxFrames);
78   ASSERT_EQ(buffer.GetBeginPosition(), buffer.GetEndPosition());
79 
80   constexpr int frames_per_bus = kMaxFrames / 4;
81   const auto bus = media::AudioBus::Create(kChannels, frames_per_bus);
82   std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 1.0);
83 
84   // Fill the buffer.
85   DelayBuffer::FrameTicks position = 0;
86   for (int i = 0; i < 4; ++i) {
87     buffer.Write(position, *bus, 1.0);
88     position += frames_per_bus;
89   }
90   EXPECT_EQ(0, buffer.GetBeginPosition());
91   EXPECT_EQ(position, buffer.GetEndPosition());
92 
93   // Read before the begin position and expect to get silence.
94   std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
95   buffer.Read(-kMaxFrames, frames_per_bus, bus.get());
96   EXPECT_BUS_VALUES_EQ(bus, 0, frames_per_bus, 0.0);
97 
98   // Read at a position one before the begin position. Expect the first sample
99   // to be 0.0, and the rest 1.0.
100   std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
101   buffer.Read(buffer.GetBeginPosition() - 1, frames_per_bus, bus.get());
102   EXPECT_EQ(0.0, bus->channel(0)[0]);
103   EXPECT_BUS_VALUES_EQ(bus, 1, frames_per_bus - 1, 1.0);
104 
105   // Read at a position where the last sample should be 0.0 and the rest 1.0.
106   std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
107   buffer.Read(buffer.GetEndPosition() - frames_per_bus + 1, frames_per_bus,
108               bus.get());
109   EXPECT_BUS_VALUES_EQ(bus, 0, frames_per_bus - 1, 1.0);
110   EXPECT_EQ(0.0, bus->channel(0)[frames_per_bus - 1]);
111 
112   // Read after the end position and expect to get silence.
113   std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
114   buffer.Read(kMaxFrames, frames_per_bus, bus.get());
115   EXPECT_BUS_VALUES_EQ(bus, 0, frames_per_bus, 0.0);
116 }
117 
TEST(DelayBufferTest,ReadsGapsInRecording)118 TEST(DelayBufferTest, ReadsGapsInRecording) {
119   DelayBuffer buffer(kMaxFrames);
120   ASSERT_EQ(buffer.GetBeginPosition(), buffer.GetEndPosition());
121 
122   constexpr int frames_per_bus = kMaxFrames / 4;
123   const auto bus = media::AudioBus::Create(kChannels, frames_per_bus);
124   std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 1.0);
125 
126   // Fill the buffer, but with a gap in the third quarter of it.
127   DelayBuffer::FrameTicks record_position = 0;
128   for (int i = 0; i < 4; ++i) {
129     if (i != 2) {
130       buffer.Write(record_position, *bus, 1.0);
131     }
132     record_position += frames_per_bus;
133   }
134   EXPECT_EQ(0, buffer.GetBeginPosition());
135   EXPECT_EQ(record_position, buffer.GetEndPosition());
136 
137   // Read through the whole range, but offset by one frame early. Confirm the
138   // silence gap appears in the right place.
139   DelayBuffer::FrameTicks read_position = -1;
140   std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
141   buffer.Read(read_position, frames_per_bus, bus.get());
142   read_position += frames_per_bus;
143   EXPECT_EQ(0.0, bus->channel(0)[0]);
144   EXPECT_BUS_VALUES_EQ(bus, 1, frames_per_bus - 1, 1.0);
145 
146   std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
147   buffer.Read(read_position, frames_per_bus, bus.get());
148   read_position += frames_per_bus;
149   EXPECT_BUS_VALUES_EQ(bus, 0, frames_per_bus, 1.0);
150 
151   std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
152   buffer.Read(read_position, frames_per_bus, bus.get());
153   read_position += frames_per_bus;
154   EXPECT_EQ(1.0, bus->channel(0)[0]);
155   // The gap begins.
156   EXPECT_BUS_VALUES_EQ(bus, 1, frames_per_bus - 1, 0.0);
157 
158   std::fill(bus->channel(0), bus->channel(0) + frames_per_bus, 0.5);
159   buffer.Read(read_position, frames_per_bus, bus.get());
160   read_position += frames_per_bus;
161   EXPECT_EQ(0.0, bus->channel(0)[0]);
162   // The gap ends.
163   EXPECT_BUS_VALUES_EQ(bus, 1, frames_per_bus - 1, 1.0);
164 }
165 
166 }  // namespace
167 }  // namespace audio
168