Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 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 indexes starting from | |
| 19 // |frameCounter|. Then returns the increased |frameCounter|. | |
| 20 // (e.g. [c + 0, c + 1, c + 2, c + 3, c + 4, ...]) | |
|
Raymond Toy
2017/01/27 17:39:44
Without looking at the code, what is c? How is fr
hongchan
2017/01/27 22:39:14
Not sure how to rephrase this better. I think it i
| |
| 21 size_t fillBusWithFrameCounter(AudioBus* targetBus, size_t frameCounter) { | |
| 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>(frameCounter + i); | |
| 26 } | |
| 27 } | |
| 28 return frameCounter + 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 // Data type for FIFO actions {"PUSH", "PULL"} with the frame count. | |
|
Raymond Toy
2017/01/27 17:39:44
Put these comments with the variables below. |typ
hongchan
2017/01/27 22:39:14
Done.
| |
| 48 struct FIFOAction { | |
| 49 const char* type; | |
| 50 const size_t frames; | |
| 51 }; | |
| 52 | |
| 53 // Test setup data container. The |actions| vector contains a list of FIFO | |
| 54 // actions that needs to be performed. | |
| 55 struct FIFOTestSetup { | |
| 56 const size_t fifoLength; | |
| 57 const unsigned numberOfChannels; | |
| 58 const std::vector<FIFOAction> actions; | |
| 59 }; | |
| 60 | |
| 61 // Data type of AudioBus verification; an index and the associated value. | |
|
Raymond Toy
2017/01/27 17:39:44
This doesn't help me to understand what |index| an
hongchan
2017/01/27 22:39:14
Done.
| |
| 62 struct AudioBusSample { | |
| 63 const size_t index; | |
| 64 const float value; | |
| 65 }; | |
| 66 | |
| 67 // Data container for the expected result. Note that |fifoSamples| and | |
| 68 // |outputSamples| contain a list of |AudioBusSample| entries for multiple | |
| 69 // verification points. | |
| 70 struct FIFOTestExpectedState { | |
| 71 const size_t indexRead; | |
| 72 const size_t indexWrite; | |
|
Raymond Toy
2017/01/27 17:39:44
Document what these two really mean.
hongchan
2017/01/27 22:39:14
Done.
| |
| 73 const unsigned overflowCount; | |
| 74 const unsigned underflowCount; | |
| 75 const std::vector<AudioBusSample> fifoSamples; | |
| 76 const std::vector<AudioBusSample> outputSamples; | |
| 77 }; | |
| 78 | |
| 79 // The data structure for the parameterized test cases. | |
| 80 struct FIFOTestParam { | |
| 81 FIFOTestSetup setup; | |
| 82 FIFOTestExpectedState expectedState; | |
| 83 }; | |
| 84 | |
| 85 std::ostream& operator<<(std::ostream& out, const FIFOTestParam& param) { | |
| 86 out << "fifoLength=" << param.setup.fifoLength | |
| 87 << "numberOfChannels=" << param.setup.numberOfChannels; | |
| 88 return out; | |
| 89 } | |
| 90 | |
| 91 FIFOTestParam basicFIFOTestParams[] = { | |
| 92 | |
| 93 // 1. Push 1024 frames first then pull 1024 frames. | |
|
Raymond Toy
2017/01/27 17:39:44
It would help if there were a contract/documentati
hongchan
2017/01/27 22:39:14
Added several comments in the FIFO header file.
| |
| 94 {{8192, 2, {{"PUSH", 1024}, {"PULL", 1024}}}, | |
| 95 {1024, 1024, 0, 0, {{1024, 0}}, {{0, 0}, {1023, 1023}}}}, | |
| 96 | |
| 97 // 2. Push 3 x 768 frames, then pull 1024 frames. 1 overflow should be | |
| 98 // recorded and the wrap-around should happen correctly. Use odd channel | |
| 99 // count. | |
| 100 {{2048, 3, {{"PUSH", 768}, {"PUSH", 768}, {"PUSH", 768}, {"PULL", 1024}}}, | |
| 101 {1280, 256, 1, 0, {{255, 2303}, {256, 256}}, {{0, 256}, {1023, 1279}}}}, | |
| 102 | |
| 103 // 3. Push 512 frames and then pull 1024. Check if underflow occurs | |
| 104 // correctly. Inspect the output bus content; the underflow will fill the | |
| 105 // second half of the output bus silence. Use odd FIFO size. | |
| 106 {{4096, 1, {{"PUSH", 512}, {"PULL", 1024}}}, | |
| 107 {512, 512, 0, 1, {{512, 0}}, {{0, 0}, {511, 511}, {512, 0}, {1023, 0}}}}, | |
| 108 | |
| 109 // 4. Push 11, 324 frames. Then pull 11, 324 frames. The most recent output | |
| 110 // must start from 11 and end with 323. Use odd FIFO size and channel | |
| 111 // count. | |
| 112 {{1234, 5, {{"PUSH", 11}, {"PUSH", 324}, {"PULL", 11}, {"PULL", 324}}}, | |
| 113 {335, 335, 0, 0, {}, {{0, 11}, {323, 334}}}}}; | |
|
o1ka
2017/01/27 13:47:54
This is nice, but what I was suggesting was a bit
hongchan
2017/01/27 22:39:14
Before modifying the test structure, I think we al
| |
| 114 | |
| 115 class PushPullFIFOTest : public ::testing::TestWithParam<FIFOTestParam> {}; | |
| 116 | |
| 117 TEST_P(PushPullFIFOTest, BasicTests) { | |
| 118 const FIFOTestSetup setup = GetParam().setup; | |
| 119 const FIFOTestExpectedState expectedState = GetParam().expectedState; | |
| 120 | |
| 121 // Create a FIFO with a specified configuration. | |
| 122 std::unique_ptr<PushPullFIFO> fifo = WTF::wrapUnique( | |
| 123 new PushPullFIFO(setup.numberOfChannels, setup.fifoLength)); | |
| 124 | |
| 125 RefPtr<AudioBus> outputBus; | |
| 126 | |
| 127 // Iterate all the scheduled push/pull actions. | |
| 128 size_t frameCounter = 0; | |
| 129 for (const auto& action : setup.actions) { | |
| 130 if (strcmp(action.type, "PUSH") == 0) { | |
| 131 RefPtr<AudioBus> inputBus = | |
| 132 AudioBus::create(setup.numberOfChannels, action.frames); | |
| 133 frameCounter = fillBusWithFrameCounter(inputBus.get(), frameCounter); | |
| 134 fifo->push(inputBus.get()); | |
| 135 LOG(INFO) << "PUSH " << action.frames | |
| 136 << " frames (frameCounter=" << frameCounter << ")"; | |
| 137 } else { | |
| 138 outputBus = AudioBus::create(setup.numberOfChannels, action.frames); | |
| 139 fifo->pull(outputBus.get(), action.frames); | |
| 140 LOG(INFO) << "PULL " << action.frames << " frames"; | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 // Get FIFO config data. | |
| 145 const PushPullFIFOStateForTest actualState = fifo->getStateForTest(); | |
| 146 | |
| 147 // Verify the read/write indexes. | |
| 148 EXPECT_EQ(actualState.indexRead, expectedState.indexRead); | |
| 149 EXPECT_EQ(actualState.indexWrite, expectedState.indexWrite); | |
| 150 EXPECT_EQ(actualState.overflowCount, expectedState.overflowCount); | |
| 151 EXPECT_EQ(actualState.underflowCount, expectedState.underflowCount); | |
| 152 | |
| 153 // Verify in-FIFO samples. | |
| 154 for (const auto& sample : expectedState.fifoSamples) { | |
| 155 EXPECT_TRUE(verifyBusValueAtIndex(fifo->bus(), sample.index, sample.value)); | |
| 156 } | |
| 157 | |
| 158 // Verify samples from the most recent output bus. | |
| 159 for (const auto& sample : expectedState.outputSamples) { | |
| 160 EXPECT_TRUE( | |
| 161 verifyBusValueAtIndex(outputBus.get(), sample.index, sample.value)); | |
| 162 } | |
| 163 } | |
| 164 | |
| 165 INSTANTIATE_TEST_CASE_P(PushPullFIFOTest, | |
| 166 PushPullFIFOTest, | |
| 167 ::testing::ValuesIn(basicFIFOTestParams)); | |
| 168 | |
| 169 // TODO(hongchan): Do death tests for SECURITY_CHECK(). | |
| 170 | |
| 171 } // namespace | |
| 172 | |
| 173 } // namespace blink | |
| OLD | NEW |