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: 14 AudioFifoTest() {} 15 virtual ~AudioFifoTest() {} 16 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. 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. 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. 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. 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. 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