Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: third_party/WebKit/Source/platform/audio/PushPullFIFOTest.cpp

Issue 2549093009: Introduce PushPullFIFO class and remove other FIFOs (Closed)
Patch Set: Comments and unit test Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 "platform/audio/PushPullFIFO.h"
6
7 #include "platform/audio/AudioUtilities.h"
8 #include "platform/testing/TestingPlatformSupport.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "wtf/PtrUtil.h"
11 #include <memory>
12 #include <vector>
13
14 namespace blink {
15
16 namespace {
17
18 // Check the basic contract of FIFO.
19 TEST(PushPullFIFOBasicTest, BasicTests) {
20 // This suppresses the multi-thread warning for GTest. Potently it increases
21 // the test execution time, but this specific test is very short and simple.
22 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
23
24 // FIFO length exceeding the maximum length allowed will cause crash.
25 EXPECT_DEATH(new PushPullFIFO(2, PushPullFIFO::kMaxFIFOLength + 1),
26 "m_fifoLength <= kMaxFIFOLength");
27
28 std::unique_ptr<PushPullFIFO> testFifo =
29 WTF::wrapUnique(new PushPullFIFO(2, 1024));
30
31 // The input bus length must be |AudioUtilities::kRenderQuantumFrames|.
32 RefPtr<AudioBus> inputBusOf129Frames =
33 AudioBus::create(2, AudioUtilities::kRenderQuantumFrames + 1);
34 EXPECT_DEATH(testFifo->push(inputBusOf129Frames.get()),
35 "inputBus->length.* == .*kRenderQuantumFrames");
36 RefPtr<AudioBus> inputBusOf127Frames =
37 AudioBus::create(2, AudioUtilities::kRenderQuantumFrames - 1);
38 EXPECT_DEATH(testFifo->push(inputBusOf127Frames.get()),
39 "inputBus->length.* == .*kRenderQuantumFrames");
40
41 // Pull request frames cannot exceed the length of output bus.
42 RefPtr<AudioBus> outputBusOf512Frames = AudioBus::create(2, 512);
43 EXPECT_DEATH(testFifo->pull(outputBusOf512Frames.get(), 513),
44 "framesRequested <= outputBus->length.*");
45
46 // Pull request frames cannot exceed the length of FIFO.
47 RefPtr<AudioBus> outputBusOf1025Frames = AudioBus::create(2, 1025);
48 EXPECT_DEATH(testFifo->pull(outputBusOf1025Frames.get(), 1025),
49 "framesRequested <= m_fifoLength");
50 }
51
52 // Fills each AudioChannel in an AudioBus with a series of linearly increasing
53 // values starting from |startingValue| and incrementing by 1. Then return value
54 // will be |startingValue| + |bus_length|.
55 size_t fillBusWithLinearRamp(AudioBus* targetBus, size_t startingValue) {
56 for (unsigned c = 0; c < targetBus->numberOfChannels(); ++c) {
57 float* busChannel = targetBus->channel(c)->mutableData();
58 for (size_t i = 0; i < targetBus->channel(c)->length(); ++i) {
59 busChannel[i] = static_cast<float>(startingValue + i);
60 }
61 }
62 return startingValue + targetBus->length();
63 }
64
65 // Inspect the content of AudioBus with a given set of index and value across
66 // channels.
67 bool verifyBusValueAtIndex(AudioBus* targetBus,
68 int index,
69 float expectedValue) {
70 for (unsigned c = 0; c < targetBus->numberOfChannels(); ++c) {
71 float* busChannel = targetBus->channel(c)->mutableData();
72 if (busChannel[index] != expectedValue) {
73 LOG(ERROR) << ">> [FAIL] expected " << expectedValue << " at index "
74 << index << " but got " << busChannel[index] << ".";
75 return false;
76 }
77 }
78 return true;
79 }
80
81 struct FIFOAction {
82 // The type of action; "PUSH" or "PULL".
83 const char* action;
84 // Number of frames for the operation.
85 const size_t numberOfFrames;
86 };
87
88 struct AudioBusSample {
89 // The frame index of a sample in the bus.
90 const size_t index;
91 // The value at the |index| above.
92 const float value;
93 };
94
95 struct FIFOTestSetup {
96 // Length of FIFO to be created for test case.
97 const size_t fifoLength;
98 // Channel count of FIFO to be created for test case.
99 const unsigned numberOfChannels;
100 // A list of |FIFOAction| entries to be performed in test case.
101 const std::vector<FIFOAction> fifoActions;
102 };
103
104 struct FIFOTestExpectedState {
105 // Expected read index in FIFO.
106 const size_t indexRead;
107 // Expected write index in FIFO.
108 const size_t indexWrite;
109 // Expected overflow count in FIFO.
110 const unsigned overflowCount;
111 // Expected underflow count in FIFO.
112 const unsigned underflowCount;
113 // A list of expected |AudioBusSample| entries for the FIFO bus.
114 const std::vector<AudioBusSample> fifoSamples;
115 // A list of expected |AudioBusSample| entries for the output bus.
116 const std::vector<AudioBusSample> outputSamples;
117 };
118
119 // The data structure for the parameterized test cases.
120 struct FIFOTestParam {
121 FIFOTestSetup setup;
122 FIFOTestExpectedState expectedState;
123 };
124
125 std::ostream& operator<<(std::ostream& out, const FIFOTestParam& param) {
126 out << "fifoLength=" << param.setup.fifoLength
127 << " numberOfChannels=" << param.setup.numberOfChannels;
128 return out;
129 }
130
131 class PushPullFIFOFeatureTest : public ::testing::TestWithParam<FIFOTestParam> {
132 };
133
134 TEST_P(PushPullFIFOFeatureTest, FeatureTests) {
135 const FIFOTestSetup setup = GetParam().setup;
136 const FIFOTestExpectedState expectedState = GetParam().expectedState;
137
138 // Create a FIFO with a specified configuration.
139 std::unique_ptr<PushPullFIFO> fifo = WTF::wrapUnique(
140 new PushPullFIFO(setup.numberOfChannels, setup.fifoLength));
141
142 RefPtr<AudioBus> outputBus;
143
144 // Iterate all the scheduled push/pull actions.
145 size_t frameCounter = 0;
146 for (const auto& action : setup.fifoActions) {
147 if (strcmp(action.action, "PUSH") == 0) {
148 RefPtr<AudioBus> inputBus =
149 AudioBus::create(setup.numberOfChannels, action.numberOfFrames);
150 frameCounter = fillBusWithLinearRamp(inputBus.get(), frameCounter);
151 fifo->push(inputBus.get());
152 LOG(INFO) << "PUSH " << action.numberOfFrames
153 << " frames (frameCounter=" << frameCounter << ")";
154 } else {
155 outputBus =
156 AudioBus::create(setup.numberOfChannels, action.numberOfFrames);
157 fifo->pull(outputBus.get(), action.numberOfFrames);
158 LOG(INFO) << "PULL " << action.numberOfFrames << " frames";
159 }
160 }
161
162 // Get FIFO config data.
163 const PushPullFIFOStateForTest actualState = fifo->getStateForTest();
164
165 // Verify the read/write indexes.
166 EXPECT_EQ(expectedState.indexRead, actualState.indexRead);
167 EXPECT_EQ(expectedState.indexWrite, actualState.indexWrite);
168 EXPECT_EQ(expectedState.overflowCount, actualState.overflowCount);
169 EXPECT_EQ(expectedState.underflowCount, actualState.underflowCount);
170
171 // Verify in-FIFO samples.
172 for (const auto& sample : expectedState.fifoSamples) {
173 EXPECT_TRUE(verifyBusValueAtIndex(fifo->bus(), sample.index, sample.value));
174 }
175
176 // Verify samples from the most recent output bus.
177 for (const auto& sample : expectedState.outputSamples) {
178 EXPECT_TRUE(
179 verifyBusValueAtIndex(outputBus.get(), sample.index, sample.value));
180 }
181 }
182
183 FIFOTestParam featureTestParams[] = {
184 // Test cases 0 ~ 3: Regular operation on various channel configuration.
185 // - Mono, Stereo, Quad, 5.1.
186 // - FIFO length and pull size are RQ-aligned.
187 {{512, 1, {{"PUSH", 128}, {"PUSH", 128}, {"PULL", 256}}},
o1ka 2017/02/03 10:41:17 Is FIFO length always proportional to 128? If not,
hongchan 2017/02/03 17:20:12 Many test cases below are using unusual FIFO lengt
188 {256, 256, 0, 0, {{0, 0}}, {{0, 0}, {255, 255}}}},
189
190 {{512, 2, {{"PUSH", 128}, {"PUSH", 128}, {"PULL", 256}}},
o1ka 2017/02/03 10:41:17 Other corner cases: Pull [FIFO length] samples; FI
hongchan 2017/02/03 17:20:12 Done.
191 {256, 256, 0, 0, {{0, 0}}, {{0, 0}, {255, 255}}}},
192
193 {{512, 4, {{"PUSH", 128}, {"PUSH", 128}, {"PULL", 256}}},
194 {256, 256, 0, 0, {{0, 0}}, {{0, 0}, {255, 255}}}},
195
196 {{512, 6, {{"PUSH", 128}, {"PUSH", 128}, {"PULL", 256}}},
197 {256, 256, 0, 0, {{0, 0}}, {{0, 0}, {255, 255}}}},
198
199 // Test case 4: Unusual FIFO and Pull length.
200 // - FIFO and pull length that are not RQ-aligned.
201 // - Check if the indexes are wrapping around correctly.
202 // - Check if the output bus starts and ends with correct values.
203 {{997,
204 1,
205 {
206 {"PUSH", 128},
207 {"PUSH", 128},
208 {"PUSH", 128},
209 {"PUSH", 128},
210 {"PULL", 449},
o1ka 2017/02/03 10:41:17 There are no tests here where PULL is smaller than
hongchan 2017/02/03 17:20:12 Done.
211 {"PUSH", 128},
212 {"PUSH", 128},
213 {"PUSH", 128},
214 {"PUSH", 128},
215 {"PULL", 449},
216 }},
217 // - expectedIndexRead = 898, expectedIndexWrite = 27
218 // - overflowCount = 0, underflowCount = 0
219 // - FIFO samples (index, expectedValue) = (898, 898), (27, 27)
220 // - Output bus samples (index, expectedValue) = (0, 499), (448, 897)
221 {898, 27, 0, 0, {{898, 898}, {27, 27}}, {{0, 449}, {448, 897}}}},
222
223 // Test case 5: Overflow
224 // - Check overflow counter.
225 // - After the overflow occurs, the read index must be moved to the write
226 // index. Thus pulled frames must not contain overwritten data.
227 {{512,
228 3,
229 {
230 {"PUSH", 128},
231 {"PUSH", 128},
232 {"PUSH", 128},
233 {"PUSH", 128},
234 {"PUSH", 128},
235 {"PULL", 256},
236 }},
237 // - expectedIndexRead = 384, expectedIndexWrite = 128
238 // - overflowCount = 1, underflowCount = 0
239 // - FIFO samples (index, expectedValue) = (384, 384), (128, 128)
240 // - Output bus samples (index, expectedValue) = (0, 128), (255, 383)
241 {384, 128, 1, 0, {{384, 384}, {128, 128}}, {{0, 128}, {255, 383}}}},
242
243 // Test case 6: Overflow in unusual FIFO and pull length.
244 // - Check overflow counter.
245 // - After the overflow occurs, the read index must be moved to the write
246 // index. Thus pulled frames must not contain overwritten data.
247 {{577,
248 5,
249 {
250 {"PUSH", 128},
251 {"PUSH", 128},
252 {"PUSH", 128},
253 {"PUSH", 128},
254 {"PUSH", 128},
255 {"PULL", 227},
256 }},
257 // - expectedIndexRead = 290, expectedIndexWrite = 63
258 // - overflowCount = 1, underflowCount = 0
259 // - FIFO samples (index, expectedValue) = (63, 63), (290, 290)
260 // - Output bus samples (index, expectedValue) = (0, 63), (226, 289)
261 {290, 63, 1, 0, {{63, 63}, {290, 290}}, {{0, 63}, {226, 289}}}},
262
263 // Test case 7: Underflow
264 // - Check underflow counter.
265 // - After the underflow occurs, the write index must be moved to the read
266 // index. Frames pulled after FIFO underflows must be zeroed.
267 {{512,
268 7,
269 {
270 {"PUSH", 128},
271 {"PUSH", 128},
272 {"PUSH", 128},
273 {"PULL", 384},
274 {"PUSH", 128},
275 {"PUSH", 128},
276 {"PULL", 384},
277 }},
278 // - expectedIndexRead = 128, expectedIndexWrite = 128
279 // - overflowCount = 0, underflowCount = 1
280 // - FIFO samples (index, expectedValue) = (128, 128)
281 // - Output bus samples (index, expectedValue) = (0, 384), (255, 639)
282 // (256, 0), (383, 0)
283 {128,
284 128,
285 0,
286 1,
287 {{128, 128}},
288 {{0, 384}, {255, 639}, {256, 0}, {383, 0}}}},
289
290 // Test case 8: Underflow in unusual FIFO and pull length.
291 // - Check underflow counter.
292 // - After the underflow occurs, the write index must be moved to the read
293 // index. Frames pulled after FIFO underflows must be zeroed.
294 {{523,
295 11,
296 {
297 {"PUSH", 128},
298 {"PUSH", 128},
299 {"PUSH", 128},
300 {"PULL", 383},
301 {"PUSH", 128},
302 {"PUSH", 128},
303 {"PULL", 383},
304 }},
305 // - expectedIndexRead = 117, expectedIndexWrite = 117
306 // - overflowCount = 0, underflowCount = 1
307 // - FIFO samples (index, expectedValue) = (117, 117)
308 // - Output bus samples (index, expectedValue) = (0, 383), (256, 639)
309 // (257, 0), (382, 0)
310 {117,
311 117,
312 0,
313 1,
314 {{117, 117}},
315 {{0, 383}, {256, 639}, {257, 0}, {382, 0}}}},
316
317 // Test case 9: Multiple pull from an empty FIFO.
318 // - Check underflow counter.
319 // - After the underflow occurs, the write index must be moved to the read
320 // index. Frames pulled after FIFO underflows must be zeroed.
321 {{1024,
322 11,
323 {
324 {"PUSH", 128},
325 {"PUSH", 128},
326 {"PULL", 440},
327 {"PULL", 440},
328 {"PULL", 440},
329 {"PULL", 440},
330 {"PULL", 440},
331 }},
332 // - expectedIndexRead = 117, expectedIndexWrite = 117
333 // - overflowCount = 0, underflowCount = 1
334 // - FIFO samples (index, expectedValue) = (117, 117)
335 // - Output bus samples (index, expectedValue) = (0, 383), (256, 639)
336 // (257, 0), (382, 0)
337 {256, 256, 0, 5, {{256, 0}}, {{0, 0}, {439, 0}}}}};
338
339 INSTANTIATE_TEST_CASE_P(PushPullFIFOFeatureTest,
340 PushPullFIFOFeatureTest,
341 ::testing::ValuesIn(featureTestParams));
342
343 } // namespace
344
345 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698