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 "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 // Fills each AudioChannel in an AudioBus with a series of linearly increasing | |
19 // values starting from |startingValue|. Then return value will be | |
Raymond Toy
2017/01/30 20:59:28
nit: "from |startingValue|" -> "from |startingValu
hongchan
2017/02/01 18:07:28
Done.
| |
20 // |startingValue| + |bus_length|. | |
21 size_t fillBusWithLinearRamp(AudioBus* targetBus, size_t startingValue) { | |
22 for (unsigned c = 0; c < targetBus->numberOfChannels(); ++c) { | |
23 float* busChannel = targetBus->channel(c)->mutableData(); | |
24 for (size_t i = 0; i < targetBus->channel(c)->length(); ++i) { | |
25 busChannel[i] = static_cast<float>(startingValue + i); | |
26 } | |
27 } | |
28 return startingValue + targetBus->length(); | |
29 } | |
30 | |
31 // Inspect the content of AudioBus with a given set of index and value across | |
32 // channels. | |
33 bool verifyBusValueAtIndex(AudioBus* targetBus, | |
34 int index, | |
35 float expectedValue) { | |
36 for (unsigned c = 0; c < targetBus->numberOfChannels(); ++c) { | |
37 float* busChannel = targetBus->channel(c)->mutableData(); | |
38 if (busChannel[index] != expectedValue) { | |
39 LOG(ERROR) << ">> [FAIL] expected " << expectedValue << " at index " | |
40 << index << " but got " << busChannel[index] << "."; | |
41 return false; | |
42 } | |
43 } | |
44 return true; | |
45 } | |
46 | |
47 struct FIFOAction { | |
48 // The type of action; "PUSH" or "PULL". | |
49 const char* type; | |
Raymond Toy
2017/01/30 20:59:29
"type" is too generic. Maybe "action"?
hongchan
2017/02/01 18:07:28
Done.
| |
50 // Number of frames for the operation. | |
51 const size_t numberOfFrames; | |
52 }; | |
53 | |
54 struct AudioBusSample { | |
55 // The frame index of a sample in the bus. | |
56 const size_t index; | |
57 // The value at the |index| above. | |
58 const float value; | |
59 }; | |
60 | |
61 struct FIFOTestSetup { | |
62 // Length of FIFO to be created for test case. | |
63 const size_t fifoLength; | |
64 // Channel count of FIFO to be created for test case. | |
65 const unsigned numberOfChannels; | |
66 // A list of |FIFOAction| entries to be performed in test case. | |
67 const std::vector<FIFOAction> fifoActions; | |
68 }; | |
69 | |
70 struct FIFOTestExpectedState { | |
71 // Expected read index in FIFO. | |
72 const size_t indexRead; | |
73 // Expected write index in FIFO. | |
74 const size_t indexWrite; | |
75 // Expected overflow count in FIFO. | |
76 const unsigned overflowCount; | |
77 // Expected underflow count in FIFO. | |
78 const unsigned underflowCount; | |
79 // A list of expected |AudioBusSample| entries for the FIFO bus. | |
80 const std::vector<AudioBusSample> fifoSamples; | |
81 // A list of expected |AudioBusSample| entries for the output bus. | |
82 const std::vector<AudioBusSample> outputSamples; | |
83 }; | |
84 | |
85 // The data structure for the parameterized test cases. | |
86 struct FIFOTestParam { | |
87 FIFOTestSetup setup; | |
88 FIFOTestExpectedState expectedState; | |
89 }; | |
90 | |
91 std::ostream& operator<<(std::ostream& out, const FIFOTestParam& param) { | |
92 out << "fifoLength=" << param.setup.fifoLength | |
93 << "numberOfChannels=" << param.setup.numberOfChannels; | |
94 return out; | |
95 } | |
96 | |
97 FIFOTestParam basicFIFOTestParams[] = { | |
98 | |
99 // 1. Push 1024 frames first then pull 1024 frames. | |
Raymond Toy
2017/01/30 20:59:29
How does this work? Or does this really mean you
| |
100 {{8192, 2, {{"PUSH", 1024}, {"PULL", 1024}}}, | |
101 {1024, 1024, 0, 0, {{1024, 0}}, {{0, 0}, {1023, 1023}}}}, | |
102 | |
103 // 2. Push 3 x 768 frames, then pull 1024 frames. 1 overflow should be | |
104 // recorded and the wrap-around should happen correctly. Use odd channel | |
Raymond Toy
2017/01/30 20:59:29
"odd" mean not even? Or "odd" meaning unusual? I
hongchan
2017/02/01 18:07:28
Done.
| |
105 // count. | |
106 {{2048, 3, {{"PUSH", 768}, {"PUSH", 768}, {"PUSH", 768}, {"PULL", 1024}}}, | |
107 {1280, 256, 1, 0, {{255, 2303}, {256, 256}}, {{0, 256}, {1023, 1279}}}}, | |
108 | |
109 // 3. Push 512 frames and then pull 1024. Check if underflow occurs | |
110 // correctly. Inspect the output bus content; the underflow will fill the | |
111 // second half of the output bus silence. Use odd FIFO size. | |
Raymond Toy
2017/01/30 20:59:28
If you're inspecting the output, you need a test c
hongchan
2017/02/01 18:07:28
All the verification in this test is done through
| |
112 {{4096, 1, {{"PUSH", 512}, {"PULL", 1024}}}, | |
113 {512, 512, 0, 1, {{512, 0}}, {{0, 0}, {511, 511}, {512, 0}, {1023, 0}}}}, | |
114 | |
115 // 4. Push 11, 324 frames. Then pull 11, 324 frames. The most recent output | |
Raymond Toy
2017/01/30 20:59:28
Your contract said you can only push 128 frames.
hongchan
2017/02/01 18:07:28
This is to accommodate o1ka@'s suggestion. Now we
| |
116 // must start from 11 and end with 323. Use odd FIFO size and channel | |
117 // count. | |
118 {{1234, 5, {{"PUSH", 11}, {"PUSH", 324}, {"PULL", 11}, {"PULL", 324}}}, | |
119 {335, 335, 0, 0, {}, {{0, 11}, {323, 334}}}}}; | |
120 | |
121 class PushPullFIFOTest : public ::testing::TestWithParam<FIFOTestParam> {}; | |
122 | |
123 TEST_P(PushPullFIFOTest, BasicTests) { | |
124 const FIFOTestSetup setup = GetParam().setup; | |
125 const FIFOTestExpectedState expectedState = GetParam().expectedState; | |
126 | |
127 // Create a FIFO with a specified configuration. | |
128 std::unique_ptr<PushPullFIFO> fifo = WTF::wrapUnique( | |
129 new PushPullFIFO(setup.numberOfChannels, setup.fifoLength)); | |
130 | |
131 RefPtr<AudioBus> outputBus; | |
132 | |
133 // Iterate all the scheduled push/pull actions. | |
134 size_t frameCounter = 0; | |
135 for (const auto& action : setup.fifoActions) { | |
136 if (strcmp(action.type, "PUSH") == 0) { | |
137 RefPtr<AudioBus> inputBus = | |
138 AudioBus::create(setup.numberOfChannels, action.numberOfFrames); | |
139 frameCounter = fillBusWithLinearRamp(inputBus.get(), frameCounter); | |
140 fifo->push(inputBus.get()); | |
141 LOG(INFO) << "PUSH " << action.numberOfFrames | |
142 << " frames (frameCounter=" << frameCounter << ")"; | |
143 } else { | |
144 outputBus = | |
145 AudioBus::create(setup.numberOfChannels, action.numberOfFrames); | |
146 fifo->pull(outputBus.get(), action.numberOfFrames); | |
147 LOG(INFO) << "PULL " << action.numberOfFrames << " frames"; | |
148 } | |
149 } | |
150 | |
151 // Get FIFO config data. | |
152 const PushPullFIFOStateForTest actualState = fifo->getStateForTest(); | |
153 | |
154 // Verify the read/write indexes. | |
155 EXPECT_EQ(actualState.indexRead, expectedState.indexRead); | |
156 EXPECT_EQ(actualState.indexWrite, expectedState.indexWrite); | |
157 EXPECT_EQ(actualState.overflowCount, expectedState.overflowCount); | |
158 EXPECT_EQ(actualState.underflowCount, expectedState.underflowCount); | |
159 | |
160 // Verify in-FIFO samples. | |
161 for (const auto& sample : expectedState.fifoSamples) { | |
162 EXPECT_TRUE(verifyBusValueAtIndex(fifo->bus(), sample.index, sample.value)); | |
163 } | |
164 | |
165 // Verify samples from the most recent output bus. | |
166 for (const auto& sample : expectedState.outputSamples) { | |
167 EXPECT_TRUE( | |
168 verifyBusValueAtIndex(outputBus.get(), sample.index, sample.value)); | |
169 } | |
170 } | |
171 | |
172 INSTANTIATE_TEST_CASE_P(PushPullFIFOTest, | |
173 PushPullFIFOTest, | |
174 ::testing::ValuesIn(basicFIFOTestParams)); | |
175 | |
176 // TODO(hongchan): Do death tests for SECURITY_CHECK(). | |
177 | |
178 } // namespace | |
179 | |
180 } // namespace blink | |
OLD | NEW |