Chromium Code Reviews| 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..81ca011859b5a289abfd660512a1531de61bb563 100644 |
| --- a/media/base/audio_bus_unittest.cc |
| +++ b/media/base/audio_bus_unittest.cc |
| @@ -2,6 +2,9 @@ |
| // 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 "media/audio/audio_parameters.h" |
| #include "media/base/audio_bus.h" |
| #include "media/base/channel_layout.h" |
| @@ -12,6 +15,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 +38,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)); |
|
henrika (OOO until Aug 14)
2012/08/15 09:59:37
Cool. I have never seen this before. Thanks.
|
| + 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 +67,6 @@ class AudioBusTest : public testing::Test { |
| VerifyValue(bus->channel(i), bus->frames(), 0); |
| } |
| - |
| protected: |
| std::vector<float*> data_; |
| @@ -68,14 +83,15 @@ 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()); |
| + EXPECT_EQ(bus->sample_rate(), kSampleRate); |
| } |
| -// 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,59 @@ TEST_F(AudioBusTest, Wrap) { |
| VerifyChannelData(bus.get()); |
| } |
| +// Verify an AudioBus created via wrapping a memory block works as advertised. |
|
henrika (OOO until Aug 14)
2012/08/15 09:59:37
Strange sentence. Please read it again ;-)
DaleCurtis
2012/08/16 01:54:14
Not sure what's strange about it? :)
|
| +TEST_F(AudioBusTest, WrapBlock) { |
| + // Choose a data size that allows us to slide |data| to be 16-byte unaligned. |
| + int data_size = AudioBus::ExpectedDataSize(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()); |
| + EXPECT_EQ(bus->sample_rate(), kSampleRate); |
| + |
| + // Try with an unaligned pointer. |
| + bus = AudioBus::WrapBlock(params, data.get()); |
| + VerifyParams(bus.get()); |
| + VerifyChannelData(bus.get()); |
| + EXPECT_EQ(bus->sample_rate(), kSampleRate); |
| +} |
| + |
| // 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::ExpectedDataSize(params)); |
| + ASSERT_EQ(bus2->data_size(), |
| + AudioBus::ExpectedDataSize(kChannels, kFrameCount)); |
| // Fill |bus1| with dummy data and zero out |bus2|. |
| for (int i = 0; i < bus1->channels(); ++i) |
| @@ -105,6 +170,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::ExpectedDataSize(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 +222,80 @@ 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, the last value is unused. |
| +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); |
| + |
| +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()); |
| + } |
| +} |
| + |
| +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(test_array, bus->frames(), sizeof(*kTestVectorUint8)); |
| + ASSERT_EQ(memcmp( |
| + test_array, kTestVectorUint8, arraysize(kTestVectorUint8)), 0); |
| + } |
| + { |
| + SCOPED_TRACE("int16"); |
| + int16 test_array[arraysize(kTestVectorInt16)]; |
| + bus->ToInterleaved(test_array, bus->frames(), sizeof(*kTestVectorInt16)); |
| + ASSERT_EQ(memcmp( |
| + test_array, kTestVectorInt16, arraysize(kTestVectorInt16)), 0); |
| + } |
| + { |
| + SCOPED_TRACE("int32"); |
| + int32 test_array[arraysize(kTestVectorInt32)]; |
| + bus->ToInterleaved(test_array, bus->frames(), sizeof(*kTestVectorInt32)); |
| + ASSERT_EQ(memcmp( |
| + test_array, kTestVectorInt32, arraysize(kTestVectorInt32)), 0); |
| + } |
| +} |
| + |
| } // namespace media |