• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 // TODO(henrika): add test which included |start_frame| in Consume() call.
6 
7 #include "media/base/audio_fifo.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 
10 namespace media {
11 
12 class AudioFifoTest : public testing::Test {
13  public:
AudioFifoTest()14   AudioFifoTest() {}
~AudioFifoTest()15   virtual ~AudioFifoTest() {}
16 
VerifyValue(const float data[],int size,float value)17   void VerifyValue(const float data[], int size, float value) {
18     for (int i = 0; i < size; ++i)
19       ASSERT_FLOAT_EQ(value, data[i]) << "i=" << i;
20   }
21 
22  protected:
23   DISALLOW_COPY_AND_ASSIGN(AudioFifoTest);
24 };
25 
26 // Verify that construction works as intended.
TEST_F(AudioFifoTest,Construct)27 TEST_F(AudioFifoTest, Construct) {
28   static const int kChannels = 6;
29   static const int kMaxFrameCount = 128;
30   AudioFifo fifo(kChannels, kMaxFrameCount);
31   EXPECT_EQ(fifo.frames(), 0);
32 }
33 
34 // Pushes audio bus objects to a FIFO and fill it up to different degrees.
TEST_F(AudioFifoTest,Push)35 TEST_F(AudioFifoTest, Push) {
36   static const int kChannels = 2;
37   static const int kMaxFrameCount = 128;
38   AudioFifo fifo(kChannels, kMaxFrameCount);
39   {
40     SCOPED_TRACE("Push 50%");
41     scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kMaxFrameCount / 2);
42     EXPECT_EQ(fifo.frames(), 0);
43     fifo.Push(bus.get());
44     EXPECT_EQ(fifo.frames(), bus->frames());
45     fifo.Clear();
46   }
47   {
48     SCOPED_TRACE("Push 100%");
49     scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kMaxFrameCount);
50     EXPECT_EQ(fifo.frames(), 0);
51     fifo.Push(bus.get());
52     EXPECT_EQ(fifo.frames(), bus->frames());
53     fifo.Clear();
54   }
55 }
56 
57 // Consumes audio bus objects from a FIFO and empty it to different degrees.
TEST_F(AudioFifoTest,Consume)58 TEST_F(AudioFifoTest, Consume) {
59   static const int kChannels = 2;
60   static const int kMaxFrameCount = 128;
61   AudioFifo fifo(kChannels, kMaxFrameCount);
62   {
63     scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kMaxFrameCount);
64     fifo.Push(bus.get());
65     EXPECT_EQ(fifo.frames(), kMaxFrameCount);
66   }
67   {
68     SCOPED_TRACE("Consume 50%");
69     scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kMaxFrameCount / 2);
70     fifo.Consume(bus.get(), 0, bus->frames());
71     EXPECT_TRUE(fifo.frames() == bus->frames());
72     fifo.Push(bus.get());
73     EXPECT_EQ(fifo.frames(), kMaxFrameCount);
74   }
75   {
76     SCOPED_TRACE("Consume 100%");
77     scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kMaxFrameCount);
78     fifo.Consume(bus.get(), 0, bus->frames());
79     EXPECT_EQ(fifo.frames(), 0);
80     fifo.Push(bus.get());
81     EXPECT_EQ(fifo.frames(), kMaxFrameCount);
82   }
83 }
84 
85 // Verify that the frames() method of the FIFO works as intended while
86 // appending and removing audio bus elements to/from the FIFO.
TEST_F(AudioFifoTest,FramesInFifo)87 TEST_F(AudioFifoTest, FramesInFifo) {
88   static const int kChannels = 2;
89   static const int kMaxFrameCount = 64;
90   AudioFifo fifo(kChannels, kMaxFrameCount);
91 
92   // Fill up the FIFO and verify that the size grows as it should while adding
93   // one audio frame each time.
94   scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, 1);
95   int n = 0;
96   while (fifo.frames() < kMaxFrameCount) {
97     fifo.Push(bus.get());
98     EXPECT_EQ(fifo.frames(), ++n);
99   }
100   EXPECT_EQ(fifo.frames(), kMaxFrameCount);
101 
102   // Empty the FIFO and verify that the size decreases as it should.
103   // Reduce the size of the FIFO by one frame each time.
104   while (fifo.frames() > 0) {
105     fifo.Consume(bus.get(), 0, bus->frames());
106     EXPECT_EQ(fifo.frames(), --n);
107   }
108   EXPECT_EQ(fifo.frames(), 0);
109 
110   // Verify that a steady-state size of #frames in the FIFO is maintained
111   // during a sequence of Push/Consume calls which involves wrapping. We ensure
112   // wrapping by selecting a buffer size which does divides the FIFO size
113   // with a remainder of one.
114   scoped_ptr<AudioBus> bus2 =
115       AudioBus::Create(kChannels, (kMaxFrameCount / 4) - 1);
116   const int frames_in_fifo = bus2->frames();
117   fifo.Push(bus2.get());
118   EXPECT_EQ(fifo.frames(), frames_in_fifo);
119   for (int n = 0; n < kMaxFrameCount; ++n) {
120     fifo.Push(bus2.get());
121     fifo.Consume(bus2.get(), 0, frames_in_fifo);
122     EXPECT_EQ(fifo.frames(), frames_in_fifo);
123   }
124 }
125 
126 // Perform a sequence of Push/Consume calls and verify that the data written
127 // to the FIFO is correctly retrieved, i.e., that the order is correct and the
128 // values are correct.
TEST_F(AudioFifoTest,VerifyDataValues)129 TEST_F(AudioFifoTest, VerifyDataValues) {
130   static const int kChannels = 2;
131   static const int kFrameCount = 2;
132   static const int kFifoFrameCount = 5 * kFrameCount;
133 
134   AudioFifo fifo(kChannels, kFifoFrameCount);
135   scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount);
136   EXPECT_EQ(fifo.frames(), 0);
137   EXPECT_EQ(bus->frames(), kFrameCount);
138 
139   // Start by filling up the FIFO with audio frames. The first audio frame
140   // will contain all 1's, the second all 2's etc. All channels contain the
141   // same value.
142   int value = 1;
143   while (fifo.frames() < kFifoFrameCount) {
144     for (int j = 0; j < bus->channels(); ++j)
145       std::fill(bus->channel(j), bus->channel(j) + bus->frames(), value);
146     fifo.Push(bus.get());
147     EXPECT_EQ(fifo.frames(), bus->frames() * value);
148     ++value;
149   }
150 
151   // FIFO should be full now.
152   EXPECT_EQ(fifo.frames(), kFifoFrameCount);
153 
154   // Consume all audio frames in the FIFO and verify that the stored values
155   // are correct. In this example, we shall read out: 1, 2, 3, 4, 5 in that
156   // order. Note that we set |frames_to_consume| to half the size of the bus.
157   // It means that we shall read out the same value two times in row.
158   value = 1;
159   int n = 1;
160   const int frames_to_consume = bus->frames() / 2;
161   while (fifo.frames() > 0) {
162     fifo.Consume(bus.get(), 0, frames_to_consume);
163     for (int j = 0; j < bus->channels(); ++j)
164       VerifyValue(bus->channel(j), frames_to_consume, value);
165     if (n++ % 2 == 0)
166       ++value;  // counts 1, 1, 2, 2, 3, 3,...
167   }
168 
169   // FIFO should be empty now.
170   EXPECT_EQ(fifo.frames(), 0);
171 
172   // Push one audio bus to the FIFO and fill it with 1's.
173   value = 1;
174   for (int j = 0; j < bus->channels(); ++j)
175     std::fill(bus->channel(j), bus->channel(j) + bus->frames(), value);
176   fifo.Push(bus.get());
177   EXPECT_EQ(fifo.frames(), bus->frames());
178 
179   // Keep calling Consume/Push a few rounds and verify that we read out the
180   // correct values. The number of elements shall be fixed (kFrameCount) during
181   // this phase.
182   for (int i = 0; i < 5 * kFifoFrameCount; i++) {
183     fifo.Consume(bus.get(), 0, bus->frames());
184     for (int j = 0; j < bus->channels(); ++j) {
185       VerifyValue(bus->channel(j), bus->channels(), value);
186       std::fill(bus->channel(j), bus->channel(j) + bus->frames(), value + 1);
187     }
188     fifo.Push(bus.get());
189     EXPECT_EQ(fifo.frames(), bus->frames());
190     ++value;
191   }
192 }
193 
194 }  // namespace media
195