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

Unified Diff: third_party/WebKit/Source/platform/audio/PushPullFIFOTest.cpp

Issue 2549093009: Introduce PushPullFIFO class and remove other FIFOs (Closed)
Patch Set: Handling corner cases and added a unit test Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/audio/PushPullFIFOTest.cpp
diff --git a/third_party/WebKit/Source/platform/audio/PushPullFIFOTest.cpp b/third_party/WebKit/Source/platform/audio/PushPullFIFOTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3657aeae7c457110db9ab5eda21b42c67df16036
--- /dev/null
+++ b/third_party/WebKit/Source/platform/audio/PushPullFIFOTest.cpp
@@ -0,0 +1,162 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "platform/audio/PushPullFIFO.h"
+
+#include "platform/testing/TestingPlatformSupport.h"
+#include "testing/gtest/include/gtest/gtest-death-test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "wtf/PtrUtil.h"
+#include <memory>
+
+namespace blink {
+
+namespace {
+
+const unsigned kNumberOfChannel = 2;
+const size_t kFIFOSize = 8192;
+const size_t kCallbackBufferSize = 1024;
Raymond Toy 2017/01/12 19:29:40 If you have to pick values for this, why not use "
o1ka 2017/01/13 11:23:44 I believe we need to have parametrized tests (TEST
hongchan 2017/01/13 23:29:23 Please bear with me - this is my first attempt to
hongchan 2017/01/13 23:29:23 Done.
+const size_t kRenderQuantum = 128;
o1ka 2017/01/13 11:23:44 The values are multipliers of each other, so many
+
+// Fills AudioBus with a value.
+void fillBusWithValue(AudioBus* targetBus, float value) {
+ for (unsigned c = 0; c < targetBus->numberOfChannels(); ++c) {
+ float* busChannel = targetBus->channel(c)->mutableData();
+ std::fill(busChannel, busChannel + targetBus->channel(c)->length(), value);
+ }
+}
+
+// Check if AudioBus is filled with a specific value within the given range.
o1ka 2017/01/13 11:23:44 To make sure the indexes are always consistent and
hongchan 2017/01/13 23:29:23 Done.
+bool isBusConstantValueOf(AudioBus* targetBus,
+ float value,
+ unsigned startFrame,
+ unsigned endFrame) {
+ for (unsigned c = 0; c < targetBus->numberOfChannels(); ++c) {
+ const float* busChannel = targetBus->channel(c)->data();
+ for (unsigned i = startFrame; i < endFrame; ++i) {
+ if (busChannel[i] != value)
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace
+
+TEST(PushPullFIFOTest, Construction) {
+ std::unique_ptr<PushPullFIFO> fifo =
+ WTF::wrapUnique(new PushPullFIFO(kNumberOfChannel, kFIFOSize));
+
+ EXPECT_EQ(static_cast<int>(kFIFOSize), fifo->length());
+ EXPECT_EQ(0, fifo->framesAvailable());
+ EXPECT_EQ(kNumberOfChannel, fifo->numberOfChannels());
+}
+
+TEST(PushPullFIFOTest, BasicOperation) {
+ // Create a FIFO of 2X render quantum. (256 frames)
+ std::unique_ptr<PushPullFIFO> fifo =
+ WTF::wrapUnique(new PushPullFIFO(kNumberOfChannel, 2 * kRenderQuantum));
+
+ RefPtr<AudioBus> inputBus =
+ AudioBus::create(kNumberOfChannel, kRenderQuantum);
+ RefPtr<AudioBus> outputBus =
+ AudioBus::create(kNumberOfChannel, 2 * kRenderQuantum);
+
+ // Create an input vector (128 frames) of '1'.
+ fillBusWithValue(inputBus.get(), 1);
+ EXPECT_TRUE(isBusConstantValueOf(inputBus.get(), 1, 0, kRenderQuantum));
+
+ // Push and pull by 128 frames.
+ fifo->push(inputBus.get());
+ fifo->pull(outputBus.get(), kRenderQuantum);
+
+ // Thus no frames available in FIFO.
+ EXPECT_EQ(fifo->framesAvailable(), 0);
+
+ // The half of output bus should be the exact copy of input bus. The rest
+ // should be 0.
+ EXPECT_TRUE(isBusConstantValueOf(outputBus.get(), 1, 0, kRenderQuantum));
+ EXPECT_TRUE(isBusConstantValueOf(outputBus.get(), 0, kRenderQuantum,
+ 2 * kRenderQuantum));
+}
+
+TEST(PushPullFIFOTest, WrapAround) {
+ std::unique_ptr<PushPullFIFO> fifo =
+ WTF::wrapUnique(new PushPullFIFO(kNumberOfChannel, kCallbackBufferSize));
+
+ RefPtr<AudioBus> inputBus =
+ AudioBus::create(kNumberOfChannel, kRenderQuantum);
+ RefPtr<AudioBus> outputBus =
+ AudioBus::create(kNumberOfChannel, kCallbackBufferSize);
+
+ unsigned numberOfblocks = kCallbackBufferSize / kRenderQuantum;
+
+ // The first round fills the FIFO with 1.
+ fillBusWithValue(inputBus.get(), 1);
+ for (unsigned i = 0; i < numberOfblocks; ++i)
+ fifo->push(inputBus.get());
+
+ // Then pull the half of FIFO.
+ for (unsigned i = 0; i < 0.5 * numberOfblocks; ++i)
+ fifo->pull(outputBus.get(), kRenderQuantum);
+
+ // Fill the emptied half with 2. After this point the FIFO content should
+ // be { 2, 2, 2, 2, 1, 1, 1, 1 } by each 128 frame block. Note that the read
+ // index is in the middle.
+ fillBusWithValue(inputBus.get(), 2);
+ for (unsigned i = 0; i < 0.5 * numberOfblocks; ++i)
+ fifo->push(inputBus.get());
+
+ // If FIFO is pulled 8 times (numberOfBlocks), it must produce the following
+ // block sequence because of warp-around.
+ float expectedValueInBlocks[] = {1, 1, 1, 1, 2, 2, 2, 2};
+
+ for (unsigned i = 0; i < numberOfblocks; ++i) {
+ fifo->pull(outputBus.get(), kRenderQuantum);
+ EXPECT_TRUE(isBusConstantValueOf(outputBus.get(), expectedValueInBlocks[i],
+ 0, kRenderQuantum));
+ }
+}
+
+TEST(PushPullFIFOTest, Overflow) {
+ std::unique_ptr<PushPullFIFO> fifo =
+ WTF::wrapUnique(new PushPullFIFO(kNumberOfChannel, kCallbackBufferSize));
+ RefPtr<AudioBus> inputBus =
+ AudioBus::create(kNumberOfChannel, kRenderQuantum);
+
+ unsigned numberOfblocks = kCallbackBufferSize / kRenderQuantum;
+
+ // Push data up to the full capacity of FIFO.
+ fillBusWithValue(inputBus.get(), 1);
+ for (unsigned i = 0; i < numberOfblocks; ++i)
+ fifo->push(inputBus.get());
+
+ // Pushing one more time without pulling causes DCHECK failure.
+ EXPECT_DEBUG_DEATH(fifo->push(inputBus.get()), "fifoOverflow");
o1ka 2017/01/13 11:23:44 But this should not be the case in real life, righ
hongchan 2017/01/13 23:29:23 Without DCHECK, how can the test runner detect suc
+}
+
+TEST(PushPullFIFOTest, Underflow) {
+ std::unique_ptr<PushPullFIFO> fifo =
+ WTF::wrapUnique(new PushPullFIFO(kNumberOfChannel, kCallbackBufferSize));
+ RefPtr<AudioBus> inputBus =
+ AudioBus::create(kNumberOfChannel, kRenderQuantum);
+ RefPtr<AudioBus> outputBus =
+ AudioBus::create(kNumberOfChannel, kRenderQuantum);
+
+ unsigned numberOfblocks = kCallbackBufferSize / kRenderQuantum;
+
+ fillBusWithValue(inputBus.get(), 1);
+ for (unsigned i = 0; i < numberOfblocks; ++i)
+ fifo->push(inputBus.get());
+
+ // Then pull the entire FIFO content. The FIFO will be empty.
+ for (unsigned i = 0; i < numberOfblocks; ++i)
+ fifo->pull(outputBus.get(), kRenderQuantum);
+
+ // Pulling an empty FIFO results the silence.
+ fifo->pull(outputBus.get(), kRenderQuantum);
+ EXPECT_TRUE(isBusConstantValueOf(outputBus.get(), 0, 0, kRenderQuantum));
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698