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

Unified Diff: media/base/audio_bus_unittest.cc

Issue 10824304: Upgrade AudioBus to support wrapping, interleaving. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments. Created 8 years, 4 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: media/base/audio_bus_unittest.cc
diff --git a/media/base/audio_bus_unittest.cc b/media/base/audio_bus_unittest.cc
index 1f60c326fefb8b5659177dc132262b407a08bdfd..bcdc682284d3cb29aa500917866a2faa29aa5ece 100644
--- a/media/base/audio_bus_unittest.cc
+++ b/media/base/audio_bus_unittest.cc
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <limits>
+
+#include "base/stringprintf.h"
+#include "base/time.h"
#include "media/audio/audio_parameters.h"
#include "media/base/audio_bus.h"
#include "media/base/channel_layout.h"
@@ -12,6 +16,7 @@ static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_5_1;
// Use a buffer size which is intentionally not a multiple of 16; see
// kChannelAlignment in audio_bus.cc.
static const int kFrameCount = 1234;
+static const int kSampleRate = 48000;
namespace media {
@@ -34,6 +39,18 @@ class AudioBusTest : public testing::Test {
ASSERT_FLOAT_EQ(value, data[i]);
}
+ // Verify values for each channel in |result| against |expected|.
+ void VerifyBus(const AudioBus* result, const AudioBus* expected) {
+ ASSERT_EQ(expected->channels(), result->channels());
+ ASSERT_EQ(expected->frames(), result->frames());
+ for (int ch = 0; ch < result->channels(); ++ch) {
+ for (int i = 0; i < result->frames(); ++i) {
+ SCOPED_TRACE(base::StringPrintf("ch=%d, i=%d", ch, i));
+ ASSERT_FLOAT_EQ(expected->channel(ch)[i], result->channel(ch)[i]);
+ }
+ }
+ }
+
// Read and write to the full extent of the allocated channel data. Also test
// the Zero() method and verify it does as advertised. Also test data if data
// is 16-byte aligned as advertised (see kChannelAlignment in audio_bus.cc).
@@ -51,7 +68,6 @@ class AudioBusTest : public testing::Test {
VerifyValue(bus->channel(i), bus->frames(), 0);
}
-
protected:
std::vector<float*> data_;
@@ -68,14 +84,14 @@ TEST_F(AudioBusTest, Create) {
// Verify Create(...) using AudioParameters works as advertised.
TEST_F(AudioBusTest, CreateUsingAudioParameters) {
scoped_ptr<AudioBus> bus = AudioBus::Create(AudioParameters(
- AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, 48000, 32,
+ AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32,
kFrameCount));
VerifyParams(bus.get());
VerifyChannelData(bus.get());
}
-// Verify an AudioBus created via wrapping works as advertised.
-TEST_F(AudioBusTest, Wrap) {
+// Verify an AudioBus created via wrapping a vector works as advertised.
+TEST_F(AudioBusTest, WrapVector) {
data_.reserve(kChannels);
for (int i = 0; i < kChannels; ++i) {
data_.push_back(static_cast<float*>(base::AlignedAlloc(
@@ -87,10 +103,57 @@ TEST_F(AudioBusTest, Wrap) {
VerifyChannelData(bus.get());
}
+// Verify an AudioBus created via wrapping a memory block works as advertised.
+TEST_F(AudioBusTest, WrapBlock) {
+ // Choose a data size that allows us to slide |data| to be 16-byte unaligned.
+ int data_size = AudioBus::BlockSize(kChannels, kFrameCount) + 16;
+ scoped_ptr<uint8> data(new uint8[data_size]);
+
+ // Slide our pointer until it's unaligned.
+ uint8* data_unaligned = data.get();
+ while ((reinterpret_cast<uintptr_t>(data_unaligned) & 0x0F) == 0U)
+ data_unaligned++;
+
+ // Try with an aligned pointer.
+ scoped_ptr<AudioBus> bus = AudioBus::WrapBlock(
+ kChannels, kFrameCount, data.get());
+ VerifyParams(bus.get());
+ VerifyChannelData(bus.get());
+
+ // Try with an unaligned pointer.
+ bus = AudioBus::WrapBlock(kChannels, kFrameCount, data_unaligned);
+ VerifyParams(bus.get());
+ VerifyChannelData(bus.get());
+
+ // Repeat using AudioParameters.
+ AudioParameters params(
+ AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32,
+ kFrameCount);
+
+ // Try with an aligned pointer.
+ bus = AudioBus::WrapBlock(params, data.get());
+ VerifyParams(bus.get());
+ VerifyChannelData(bus.get());
+
+ // Try with an unaligned pointer.
+ bus = AudioBus::WrapBlock(params, data.get());
+ VerifyParams(bus.get());
+ VerifyChannelData(bus.get());
+}
+
// Simulate a shared memory transfer and verify results.
TEST_F(AudioBusTest, AudioData) {
+ // Create one bus with AudioParameters and the other through direct values to
+ // test for parity between the functions.
+ AudioParameters params(
+ AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32,
+ kFrameCount);
scoped_ptr<AudioBus> bus1 = AudioBus::Create(kChannels, kFrameCount);
- scoped_ptr<AudioBus> bus2 = AudioBus::Create(kChannels, kFrameCount);
+ scoped_ptr<AudioBus> bus2 = AudioBus::Create(params);
+ // Flip the order of which bus checks using params vs created with for parity.
+ ASSERT_EQ(bus1->data_size(), AudioBus::BlockSize(params));
+ ASSERT_EQ(bus2->data_size(),
+ AudioBus::BlockSize(kChannels, kFrameCount));
// Fill |bus1| with dummy data and zero out |bus2|.
for (int i = 0; i < bus1->channels(); ++i)
@@ -105,6 +168,39 @@ TEST_F(AudioBusTest, AudioData) {
VerifyValue(bus2->channel(i), bus2->frames(), i);
}
+// Simulate a shared memory transfer from a wrapped to unwrapped AudioBus.
+TEST_F(AudioBusTest, AudioDataWrapped) {
+ // Create one bus with AudioParameters and the other through direct values to
+ // test for parity between the functions.
+ AudioParameters params(
+ AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32,
+ kFrameCount);
+ scoped_ptr<AudioBus> bus1 = AudioBus::Create(kChannels, kFrameCount);
+ ASSERT_EQ(bus1->data_size(), AudioBus::BlockSize(params));
+ scoped_ptr<AudioBus> bus2 = AudioBus::WrapBlock(params, bus1->data());
+
+ // Fill |bus1| with dummy data.
+ for (int i = 0; i < bus1->channels(); ++i)
+ std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i);
+
+ // Verify the data is correct inside of |bus2|.
+ for (int i = 0; i < bus2->channels(); ++i)
+ VerifyValue(bus2->channel(i), bus2->frames(), i);
+
+ // Zero |bus2| and ensure |bus1| is zero'd
+ bus2->Zero();
+ for (int i = 0; i < bus1->channels(); ++i)
+ VerifyValue(bus1->channel(i), bus1->frames(), 0);
+
+ // Fill |bus2| with dummy data.
+ for (int i = 0; i < bus2->channels(); ++i)
+ std::fill(bus2->channel(i), bus2->channel(i) + bus2->frames(), i);
+
+ // Verify the data is correct inside of |bus1|.
+ for (int i = 0; i < bus1->channels(); ++i)
+ VerifyValue(bus1->channel(i), bus1->frames(), i);
+}
+
// Verify Zero() and ZeroFrames(...) utility methods work as advertised.
TEST_F(AudioBusTest, Zero) {
scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount);
@@ -124,4 +220,82 @@ TEST_F(AudioBusTest, Zero) {
VerifyValue(bus->channel(i), bus->frames(), 0);
}
+// Each test vector represents two channels of data in the following arbitrary
+// layout: <min, zero, max, min, zero, max, zero, zero>.
+static const int kTestVectorSize = 8;
+static const uint8 kTestVectorUint8[kTestVectorSize] = {
+ 0, -kint8min, kuint8max, 0, -kint8min, kuint8max, -kint8min, -kint8min };
+static const int16 kTestVectorInt16[kTestVectorSize] = {
+ kint16min, 0, kint16max, kint16min, 0, kint16max, 0, 0 };
+static const int32 kTestVectorInt32[kTestVectorSize] = {
+ kint32min, 0, kint32max, kint32min, 0, kint32max, 0, 0 };
+
+// Expected results.
+static const int kTestVectorFrames = kTestVectorSize / 2;
+static const float kTestVectorResult[][kTestVectorFrames] = {
+ { -1, 1, 0, 0 }, { 0, -1, 1, 0 }};
+static const int kTestVectorChannels = arraysize(kTestVectorResult);
+
+// Verify FromInterleaved() deinterleaves audio in suported formats correctly.
+TEST_F(AudioBusTest, FromInterleaved) {
+ scoped_ptr<AudioBus> bus = AudioBus::Create(
+ kTestVectorChannels, kTestVectorFrames);
+ scoped_ptr<AudioBus> expected = AudioBus::Create(
+ kTestVectorChannels, kTestVectorFrames);
+ for (int ch = 0; ch < kTestVectorChannels; ++ch) {
+ memcpy(expected->channel(ch), kTestVectorResult[ch],
+ kTestVectorFrames * sizeof(*expected->channel(ch)));
+ }
+ {
+ SCOPED_TRACE("uint8");
+ bus->FromInterleaved(
+ kTestVectorUint8, kTestVectorFrames, sizeof(*kTestVectorUint8));
+ VerifyBus(bus.get(), expected.get());
+ }
+ {
+ SCOPED_TRACE("int16");
+ bus->FromInterleaved(
+ kTestVectorInt16, kTestVectorFrames, sizeof(*kTestVectorInt16));
+ VerifyBus(bus.get(), expected.get());
+ }
+ {
+ SCOPED_TRACE("int32");
+ bus->FromInterleaved(
+ kTestVectorInt32, kTestVectorFrames, sizeof(*kTestVectorInt32));
+ VerifyBus(bus.get(), expected.get());
+ }
+}
+
+// Verify ToInterleaved() interleaves audio in suported formats correctly.
+TEST_F(AudioBusTest, ToInterleaved) {
+ scoped_ptr<AudioBus> bus = AudioBus::Create(
+ kTestVectorChannels, kTestVectorFrames);
+ // Fill the bus with our test vector.
+ for (int ch = 0; ch < kTestVectorChannels; ++ch) {
+ memcpy(bus->channel(ch), kTestVectorResult[ch],
+ kTestVectorFrames * sizeof(*bus->channel(ch)));
+ }
+ {
+ SCOPED_TRACE("uint8");
+ uint8 test_array[arraysize(kTestVectorUint8)];
+ bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorUint8), test_array);
+ ASSERT_EQ(memcmp(
+ test_array, kTestVectorUint8, arraysize(kTestVectorUint8)), 0);
+ }
+ {
+ SCOPED_TRACE("int16");
+ int16 test_array[arraysize(kTestVectorInt16)];
+ bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt16), test_array);
+ ASSERT_EQ(memcmp(
+ test_array, kTestVectorInt16, arraysize(kTestVectorInt16)), 0);
+ }
+ {
+ SCOPED_TRACE("int32");
+ int32 test_array[arraysize(kTestVectorInt32)];
+ bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt32), test_array);
+ ASSERT_EQ(memcmp(
+ test_array, kTestVectorInt32, arraysize(kTestVectorInt32)), 0);
+ }
+}
+
} // namespace media

Powered by Google App Engine
This is Rietveld 408576698