OLD | NEW |
---|---|
(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 <memory> | |
8 #include <vector> | |
9 #include "platform/audio/AudioUtilities.h" | |
10 #include "platform/testing/TestingPlatformSupport.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 #include "wtf/PtrUtil.h" | |
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"); | |
Nico
2017/02/08 19:59:28
CHECK strings are discarded in official builds, wh
| |
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}}}, | |
188 {256, 256, 0, 0, {{0, 0}}, {{0, 0}, {255, 255}}}}, | |
189 | |
190 {{512, 2, {{"PUSH", 128}, {"PUSH", 128}, {"PULL", 256}}}, | |
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: Pull size less than or equal to 128. | |
200 {{128, 2, {{"PUSH", 128}, {"PULL", 128}, {"PUSH", 128}, {"PULL", 64}}}, | |
201 {64, 0, 0, 0, {{64, 192}, {0, 128}}, {{0, 128}, {63, 191}}}}, | |
202 | |
203 // Test case 5: Unusual FIFO and Pull length. | |
204 // - FIFO and pull length that are not aligned to render quantum. | |
205 // - Check if the indexes are wrapping around correctly. | |
206 // - Check if the output bus starts and ends with correct values. | |
207 {{997, | |
208 1, | |
209 { | |
210 {"PUSH", 128}, | |
211 {"PUSH", 128}, | |
212 {"PUSH", 128}, | |
213 {"PUSH", 128}, | |
214 {"PULL", 449}, | |
215 {"PUSH", 128}, | |
216 {"PUSH", 128}, | |
217 {"PUSH", 128}, | |
218 {"PUSH", 128}, | |
219 {"PULL", 449}, | |
220 }}, | |
221 // - expectedIndexRead = 898, expectedIndexWrite = 27 | |
222 // - overflowCount = 0, underflowCount = 0 | |
223 // - FIFO samples (index, expectedValue) = (898, 898), (27, 27) | |
224 // - Output bus samples (index, expectedValue) = (0, 499), (448, 897) | |
225 {898, 27, 0, 0, {{898, 898}, {27, 27}}, {{0, 449}, {448, 897}}}}, | |
226 | |
227 // Test case 6: Overflow | |
228 // - Check overflow counter. | |
229 // - After the overflow occurs, the read index must be moved to the write | |
230 // index. Thus pulled frames must not contain overwritten data. | |
231 {{512, | |
232 3, | |
233 { | |
234 {"PUSH", 128}, | |
235 {"PUSH", 128}, | |
236 {"PUSH", 128}, | |
237 {"PUSH", 128}, | |
238 {"PUSH", 128}, | |
239 {"PULL", 256}, | |
240 }}, | |
241 // - expectedIndexRead = 384, expectedIndexWrite = 128 | |
242 // - overflowCount = 1, underflowCount = 0 | |
243 // - FIFO samples (index, expectedValue) = (384, 384), (128, 128) | |
244 // - Output bus samples (index, expectedValue) = (0, 128), (255, 383) | |
245 {384, 128, 1, 0, {{384, 384}, {128, 128}}, {{0, 128}, {255, 383}}}}, | |
246 | |
247 // Test case 7: Overflow in unusual FIFO and pull length. | |
248 // - Check overflow counter. | |
249 // - After the overflow occurs, the read index must be moved to the write | |
250 // index. Thus pulled frames must not contain overwritten data. | |
251 {{577, | |
252 5, | |
253 { | |
254 {"PUSH", 128}, | |
255 {"PUSH", 128}, | |
256 {"PUSH", 128}, | |
257 {"PUSH", 128}, | |
258 {"PUSH", 128}, | |
259 {"PULL", 227}, | |
260 }}, | |
261 // - expectedIndexRead = 290, expectedIndexWrite = 63 | |
262 // - overflowCount = 1, underflowCount = 0 | |
263 // - FIFO samples (index, expectedValue) = (63, 63), (290, 290) | |
264 // - Output bus samples (index, expectedValue) = (0, 63), (226, 289) | |
265 {290, 63, 1, 0, {{63, 63}, {290, 290}}, {{0, 63}, {226, 289}}}}, | |
266 | |
267 // Test case 8: Underflow | |
268 // - Check underflow counter. | |
269 // - After the underflow occurs, the write index must be moved to the read | |
270 // index. Frames pulled after FIFO underflows must be zeroed. | |
271 {{512, | |
272 7, | |
273 { | |
274 {"PUSH", 128}, | |
275 {"PUSH", 128}, | |
276 {"PUSH", 128}, | |
277 {"PULL", 384}, | |
278 {"PUSH", 128}, | |
279 {"PUSH", 128}, | |
280 {"PULL", 384}, | |
281 }}, | |
282 // - expectedIndexRead = 128, expectedIndexWrite = 128 | |
283 // - overflowCount = 0, underflowCount = 1 | |
284 // - FIFO samples (index, expectedValue) = (128, 128) | |
285 // - Output bus samples (index, expectedValue) = (0, 384), (255, 639) | |
286 // (256, 0), (383, 0) | |
287 {128, | |
288 128, | |
289 0, | |
290 1, | |
291 {{128, 128}}, | |
292 {{0, 384}, {255, 639}, {256, 0}, {383, 0}}}}, | |
293 | |
294 // Test case 9: Underflow in unusual FIFO and pull length. | |
295 // - Check underflow counter. | |
296 // - After the underflow occurs, the write index must be moved to the read | |
297 // index. Frames pulled after FIFO underflows must be zeroed. | |
298 {{523, | |
299 11, | |
300 { | |
301 {"PUSH", 128}, | |
302 {"PUSH", 128}, | |
303 {"PUSH", 128}, | |
304 {"PULL", 383}, | |
305 {"PUSH", 128}, | |
306 {"PUSH", 128}, | |
307 {"PULL", 383}, | |
308 }}, | |
309 // - expectedIndexRead = 117, expectedIndexWrite = 117 | |
310 // - overflowCount = 0, underflowCount = 1 | |
311 // - FIFO samples (index, expectedValue) = (117, 117) | |
312 // - Output bus samples (index, expectedValue) = (0, 383), (256, 639) | |
313 // (257, 0), (382, 0) | |
314 {117, | |
315 117, | |
316 0, | |
317 1, | |
318 {{117, 117}}, | |
319 {{0, 383}, {256, 639}, {257, 0}, {382, 0}}}}, | |
320 | |
321 // Test case 10: Multiple pull from an empty FIFO. | |
322 // - Check underflow counter. | |
323 // - After the underflow occurs, the write index must be moved to the read | |
324 // index. Frames pulled after FIFO underflows must be zeroed. | |
325 {{1024, | |
326 11, | |
327 { | |
328 {"PUSH", 128}, | |
329 {"PUSH", 128}, | |
330 {"PULL", 440}, | |
331 {"PULL", 440}, | |
332 {"PULL", 440}, | |
333 {"PULL", 440}, | |
334 {"PULL", 440}, | |
335 }}, | |
336 // - expectedIndexRead = 117, expectedIndexWrite = 117 | |
337 // - overflowCount = 0, underflowCount = 1 | |
338 // - FIFO samples (index, expectedValue) = (117, 117) | |
339 // - Output bus samples (index, expectedValue) = (0, 383), (256, 639) | |
340 // (257, 0), (382, 0) | |
341 {256, 256, 0, 5, {{256, 0}}, {{0, 0}, {439, 0}}}}, | |
342 | |
343 // Test case 11: Multiple pull from an empty FIFO. (zero push) | |
344 {{1024, | |
345 11, | |
346 { | |
347 {"PULL", 144}, | |
348 {"PULL", 144}, | |
349 {"PULL", 144}, | |
350 {"PULL", 144}, | |
351 }}, | |
352 // - expectedIndexRead = 0, expectedIndexWrite = 0 | |
353 // - overflowCount = 0, underflowCount = 4 | |
354 // - FIFO samples (index, expectedValue) = (0, 0), (1023, 0) | |
355 // - Output bus samples (index, expectedValue) = (0, 0), (143, 0) | |
356 {0, 0, 0, 4, {{0, 0}, {1023, 0}}, {{0, 0}, {143, 0}}}}}; | |
357 | |
358 INSTANTIATE_TEST_CASE_P(PushPullFIFOFeatureTest, | |
359 PushPullFIFOFeatureTest, | |
360 ::testing::ValuesIn(featureTestParams)); | |
361 | |
362 } // namespace | |
363 | |
364 } // namespace blink | |
OLD | NEW |