| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 14 #include "build/build_config.h" | 14 #include "build/build_config.h" |
| 15 #include "media/base/audio_bus.h" | 15 #include "media/base/audio_bus.h" |
| 16 #include "media/base/audio_parameters.h" | 16 #include "media/base/audio_parameters.h" |
| 17 #include "media/base/audio_sample_types.h" |
| 17 #include "media/base/channel_layout.h" | 18 #include "media/base/channel_layout.h" |
| 18 #include "media/base/fake_audio_render_callback.h" | 19 #include "media/base/fake_audio_render_callback.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 21 |
| 21 namespace media { | 22 namespace media { |
| 22 | 23 |
| 23 static const int kChannels = 6; | 24 static const int kChannels = 6; |
| 24 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_5_1; | 25 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_5_1; |
| 25 // Use a buffer size which is intentionally not a multiple of kChannelAlignment. | 26 // Use a buffer size which is intentionally not a multiple of kChannelAlignment. |
| 26 static const int kFrameCount = media::AudioBus::kChannelAlignment * 32 - 1; | 27 static const int kFrameCount = media::AudioBus::kChannelAlignment * 32 - 1; |
| 27 static const int kSampleRate = 48000; | 28 static const int kSampleRate = 48000; |
| 28 | 29 |
| 29 class AudioBusTest : public testing::Test { | 30 class AudioBusTest : public testing::Test { |
| 30 public: | 31 public: |
| 31 AudioBusTest() {} | 32 AudioBusTest() {} |
| 32 ~AudioBusTest() override { | 33 ~AudioBusTest() override { |
| 33 for (size_t i = 0; i < data_.size(); ++i) | 34 for (size_t i = 0; i < data_.size(); ++i) |
| 34 base::AlignedFree(data_[i]); | 35 base::AlignedFree(data_[i]); |
| 35 } | 36 } |
| 36 | 37 |
| 37 // Validate parameters returned by AudioBus v.s. the constructed parameters. | 38 void VerifyChannelAndFrameCount(AudioBus* bus) { |
| 38 void VerifyParams(AudioBus* bus) { | |
| 39 EXPECT_EQ(kChannels, bus->channels()); | 39 EXPECT_EQ(kChannels, bus->channels()); |
| 40 EXPECT_EQ(kFrameCount, bus->frames()); | 40 EXPECT_EQ(kFrameCount, bus->frames()); |
| 41 } | 41 } |
| 42 | 42 |
| 43 void VerifyValue(const float data[], int size, float value) { | 43 void VerifyArrayIsFilledWithValue(const float data[], int size, float value) { |
| 44 for (int i = 0; i < size; ++i) | 44 for (int i = 0; i < size; ++i) |
| 45 ASSERT_FLOAT_EQ(value, data[i]) << "i=" << i; | 45 ASSERT_FLOAT_EQ(value, data[i]) << "i=" << i; |
| 46 } | 46 } |
| 47 | 47 |
| 48 // Verify values for each channel in |result| are within |epsilon| of | 48 // Verify values for each channel in |result| are within |epsilon| of |
| 49 // |expected|. If |epsilon| exactly equals 0, uses FLOAT_EQ macro. | 49 // |expected|. If |epsilon| exactly equals 0, uses FLOAT_EQ macro. |
| 50 void VerifyBusWithEpsilon(const AudioBus* result, const AudioBus* expected, | 50 void VerifyAreEqualWithEpsilon(const AudioBus* result, |
| 51 float epsilon) { | 51 const AudioBus* expected, |
| 52 float epsilon) { |
| 52 ASSERT_EQ(expected->channels(), result->channels()); | 53 ASSERT_EQ(expected->channels(), result->channels()); |
| 53 ASSERT_EQ(expected->frames(), result->frames()); | 54 ASSERT_EQ(expected->frames(), result->frames()); |
| 54 for (int ch = 0; ch < result->channels(); ++ch) { | 55 for (int ch = 0; ch < result->channels(); ++ch) { |
| 55 for (int i = 0; i < result->frames(); ++i) { | 56 for (int i = 0; i < result->frames(); ++i) { |
| 56 SCOPED_TRACE(base::StringPrintf("ch=%d, i=%d", ch, i)); | 57 SCOPED_TRACE(base::StringPrintf("ch=%d, i=%d", ch, i)); |
| 57 if (epsilon == 0) { | 58 if (epsilon == 0) { |
| 58 ASSERT_FLOAT_EQ(expected->channel(ch)[i], result->channel(ch)[i]); | 59 ASSERT_FLOAT_EQ(expected->channel(ch)[i], result->channel(ch)[i]); |
| 59 } else { | 60 } else { |
| 60 ASSERT_NEAR(expected->channel(ch)[i], result->channel(ch)[i], | 61 ASSERT_NEAR(expected->channel(ch)[i], result->channel(ch)[i], |
| 61 epsilon); | 62 epsilon); |
| 62 } | 63 } |
| 63 } | 64 } |
| 64 } | 65 } |
| 65 } | 66 } |
| 66 | 67 |
| 67 // Verify values for each channel in |result| against |expected|. | 68 // Verify values for each channel in |result| against |expected|. |
| 68 void VerifyBus(const AudioBus* result, const AudioBus* expected) { | 69 void VerifyAreEqual(const AudioBus* result, const AudioBus* expected) { |
| 69 VerifyBusWithEpsilon(result, expected, 0); | 70 VerifyAreEqualWithEpsilon(result, expected, 0); |
| 70 } | 71 } |
| 71 | 72 |
| 72 // Read and write to the full extent of the allocated channel data. Also test | 73 // Read and write to the full extent of the allocated channel data. Also test |
| 73 // the Zero() method and verify it does as advertised. Also test data if data | 74 // the Zero() method and verify it does as advertised. Also test data if data |
| 74 // is 16-byte aligned as advertised (see kChannelAlignment in audio_bus.h). | 75 // is 16-byte aligned as advertised (see kChannelAlignment in audio_bus.h). |
| 75 void VerifyChannelData(AudioBus* bus) { | 76 void VerifyReadWriteAndAlignment(AudioBus* bus) { |
| 76 for (int i = 0; i < bus->channels(); ++i) { | 77 for (int i = 0; i < bus->channels(); ++i) { |
| 78 // Verify that the address returned by channel(i) is a multiple of |
| 79 // AudioBus::kChannelAlignment. |
| 77 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>( | 80 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>( |
| 78 bus->channel(i)) & (AudioBus::kChannelAlignment - 1)); | 81 bus->channel(i)) & (AudioBus::kChannelAlignment - 1)); |
| 82 |
| 83 // Write into the channel buffer. |
| 79 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i); | 84 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i); |
| 80 } | 85 } |
| 81 | 86 |
| 82 for (int i = 0; i < bus->channels(); ++i) | 87 for (int i = 0; i < bus->channels(); ++i) |
| 83 VerifyValue(bus->channel(i), bus->frames(), i); | 88 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), i); |
| 84 | 89 |
| 85 bus->Zero(); | 90 bus->Zero(); |
| 86 for (int i = 0; i < bus->channels(); ++i) | 91 for (int i = 0; i < bus->channels(); ++i) |
| 87 VerifyValue(bus->channel(i), bus->frames(), 0); | 92 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0); |
| 88 } | 93 } |
| 89 | 94 |
| 90 // Verify copying to and from |bus1| and |bus2|. | 95 // Verify copying to and from |bus1| and |bus2|. |
| 91 void CopyTest(AudioBus* bus1, AudioBus* bus2) { | 96 void CopyTest(AudioBus* bus1, AudioBus* bus2) { |
| 92 // Fill |bus1| with dummy data. | 97 // Fill |bus1| with dummy data. |
| 93 for (int i = 0; i < bus1->channels(); ++i) | 98 for (int i = 0; i < bus1->channels(); ++i) |
| 94 std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i); | 99 std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i); |
| 95 | 100 |
| 96 // Verify copy from |bus1| to |bus2|. | 101 // Verify copy from |bus1| to |bus2|. |
| 97 bus2->Zero(); | 102 bus2->Zero(); |
| 98 bus1->CopyTo(bus2); | 103 bus1->CopyTo(bus2); |
| 99 VerifyBus(bus1, bus2); | 104 VerifyAreEqual(bus1, bus2); |
| 100 | 105 |
| 101 // Verify copy from |bus2| to |bus1|. | 106 // Verify copy from |bus2| to |bus1|. |
| 102 bus1->Zero(); | 107 bus1->Zero(); |
| 103 bus2->CopyTo(bus1); | 108 bus2->CopyTo(bus1); |
| 104 VerifyBus(bus2, bus1); | 109 VerifyAreEqual(bus2, bus1); |
| 105 } | 110 } |
| 106 | 111 |
| 107 protected: | 112 protected: |
| 108 std::vector<float*> data_; | 113 std::vector<float*> data_; |
| 109 | 114 |
| 110 DISALLOW_COPY_AND_ASSIGN(AudioBusTest); | 115 DISALLOW_COPY_AND_ASSIGN(AudioBusTest); |
| 111 }; | 116 }; |
| 112 | 117 |
| 113 // Verify basic Create(...) method works as advertised. | 118 // Verify basic Create(...) method works as advertised. |
| 114 TEST_F(AudioBusTest, Create) { | 119 TEST_F(AudioBusTest, Create) { |
| 115 std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); | 120 std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); |
| 116 VerifyParams(bus.get()); | 121 VerifyChannelAndFrameCount(bus.get()); |
| 117 VerifyChannelData(bus.get()); | 122 VerifyReadWriteAndAlignment(bus.get()); |
| 118 } | 123 } |
| 119 | 124 |
| 120 // Verify Create(...) using AudioParameters works as advertised. | 125 // Verify Create(...) using AudioParameters works as advertised. |
| 121 TEST_F(AudioBusTest, CreateUsingAudioParameters) { | 126 TEST_F(AudioBusTest, CreateUsingAudioParameters) { |
| 122 std::unique_ptr<AudioBus> bus = AudioBus::Create( | 127 std::unique_ptr<AudioBus> bus = AudioBus::Create( |
| 123 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, | 128 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, |
| 124 kSampleRate, 32, kFrameCount)); | 129 kSampleRate, 32, kFrameCount)); |
| 125 VerifyParams(bus.get()); | 130 VerifyChannelAndFrameCount(bus.get()); |
| 126 VerifyChannelData(bus.get()); | 131 VerifyReadWriteAndAlignment(bus.get()); |
| 127 } | 132 } |
| 128 | 133 |
| 129 // Verify an AudioBus created via wrapping a vector works as advertised. | 134 // Verify an AudioBus created via wrapping a vector works as advertised. |
| 130 TEST_F(AudioBusTest, WrapVector) { | 135 TEST_F(AudioBusTest, WrapVector) { |
| 131 data_.reserve(kChannels); | 136 data_.reserve(kChannels); |
| 132 for (int i = 0; i < kChannels; ++i) { | 137 for (int i = 0; i < kChannels; ++i) { |
| 133 data_.push_back(static_cast<float*>(base::AlignedAlloc( | 138 data_.push_back(static_cast<float*>(base::AlignedAlloc( |
| 134 sizeof(*data_[i]) * kFrameCount, AudioBus::kChannelAlignment))); | 139 sizeof(*data_[i]) * kFrameCount, AudioBus::kChannelAlignment))); |
| 135 } | 140 } |
| 136 | 141 |
| 137 std::unique_ptr<AudioBus> bus = AudioBus::WrapVector(kFrameCount, data_); | 142 std::unique_ptr<AudioBus> bus = AudioBus::WrapVector(kFrameCount, data_); |
| 138 VerifyParams(bus.get()); | 143 VerifyChannelAndFrameCount(bus.get()); |
| 139 VerifyChannelData(bus.get()); | 144 VerifyReadWriteAndAlignment(bus.get()); |
| 140 } | 145 } |
| 141 | 146 |
| 142 // Verify an AudioBus created via wrapping a memory block works as advertised. | 147 // Verify an AudioBus created via wrapping a memory block works as advertised. |
| 143 TEST_F(AudioBusTest, WrapMemory) { | 148 TEST_F(AudioBusTest, WrapMemory) { |
| 144 AudioParameters params( | 149 AudioParameters params( |
| 145 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32, | 150 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32, |
| 146 kFrameCount); | 151 kFrameCount); |
| 147 int data_size = AudioBus::CalculateMemorySize(params); | 152 int data_size = AudioBus::CalculateMemorySize(params); |
| 148 std::unique_ptr<float, base::AlignedFreeDeleter> data(static_cast<float*>( | 153 std::unique_ptr<float, base::AlignedFreeDeleter> data(static_cast<float*>( |
| 149 base::AlignedAlloc(data_size, AudioBus::kChannelAlignment))); | 154 base::AlignedAlloc(data_size, AudioBus::kChannelAlignment))); |
| 150 | 155 |
| 151 // Fill the memory with a test value we can check for after wrapping. | 156 // Fill the memory with a test value we can check for after wrapping. |
| 152 static const float kTestValue = 3; | 157 static const float kTestValue = 3; |
| 153 std::fill( | 158 std::fill( |
| 154 data.get(), data.get() + data_size / sizeof(*data.get()), kTestValue); | 159 data.get(), data.get() + data_size / sizeof(*data.get()), kTestValue); |
| 155 | 160 |
| 156 std::unique_ptr<AudioBus> bus = AudioBus::WrapMemory(params, data.get()); | 161 std::unique_ptr<AudioBus> bus = AudioBus::WrapMemory(params, data.get()); |
| 157 // Verify the test value we filled prior to wrapping. | 162 // Verify the test value we filled prior to wrapping. |
| 158 for (int i = 0; i < bus->channels(); ++i) | 163 for (int i = 0; i < bus->channels(); ++i) |
| 159 VerifyValue(bus->channel(i), bus->frames(), kTestValue); | 164 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), kTestValue); |
| 160 VerifyParams(bus.get()); | 165 VerifyChannelAndFrameCount(bus.get()); |
| 161 VerifyChannelData(bus.get()); | 166 VerifyReadWriteAndAlignment(bus.get()); |
| 162 | 167 |
| 163 // Verify the channel vectors lie within the provided memory block. | 168 // Verify the channel vectors lie within the provided memory block. |
| 164 EXPECT_GE(bus->channel(0), data.get()); | 169 EXPECT_GE(bus->channel(0), data.get()); |
| 165 EXPECT_LT(bus->channel(bus->channels() - 1) + bus->frames(), | 170 EXPECT_LT(bus->channel(bus->channels() - 1) + bus->frames(), |
| 166 data.get() + data_size / sizeof(*data.get())); | 171 data.get() + data_size / sizeof(*data.get())); |
| 167 } | 172 } |
| 168 | 173 |
| 169 // Simulate a shared memory transfer and verify results. | 174 // Simulate a shared memory transfer and verify results. |
| 170 TEST_F(AudioBusTest, CopyTo) { | 175 TEST_F(AudioBusTest, CopyTo) { |
| 171 // Create one bus with AudioParameters and the other through direct values to | 176 // Create one bus with AudioParameters and the other through direct values to |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 | 215 |
| 211 // Fill the bus with dummy data. | 216 // Fill the bus with dummy data. |
| 212 for (int i = 0; i < bus->channels(); ++i) | 217 for (int i = 0; i < bus->channels(); ++i) |
| 213 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); | 218 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); |
| 214 EXPECT_FALSE(bus->AreFramesZero()); | 219 EXPECT_FALSE(bus->AreFramesZero()); |
| 215 | 220 |
| 216 // Zero first half the frames of each channel. | 221 // Zero first half the frames of each channel. |
| 217 bus->ZeroFrames(kFrameCount / 2); | 222 bus->ZeroFrames(kFrameCount / 2); |
| 218 for (int i = 0; i < bus->channels(); ++i) { | 223 for (int i = 0; i < bus->channels(); ++i) { |
| 219 SCOPED_TRACE("First Half Zero"); | 224 SCOPED_TRACE("First Half Zero"); |
| 220 VerifyValue(bus->channel(i), kFrameCount / 2, 0); | 225 VerifyArrayIsFilledWithValue(bus->channel(i), kFrameCount / 2, 0); |
| 221 VerifyValue(bus->channel(i) + kFrameCount / 2, | 226 VerifyArrayIsFilledWithValue(bus->channel(i) + kFrameCount / 2, |
| 222 kFrameCount - kFrameCount / 2, i + 1); | 227 kFrameCount - kFrameCount / 2, i + 1); |
| 223 } | 228 } |
| 224 EXPECT_FALSE(bus->AreFramesZero()); | 229 EXPECT_FALSE(bus->AreFramesZero()); |
| 225 | 230 |
| 226 // Fill the bus with dummy data. | 231 // Fill the bus with dummy data. |
| 227 for (int i = 0; i < bus->channels(); ++i) | 232 for (int i = 0; i < bus->channels(); ++i) |
| 228 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); | 233 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); |
| 229 | 234 |
| 230 // Zero the last half of the frames. | 235 // Zero the last half of the frames. |
| 231 bus->ZeroFramesPartial(kFrameCount / 2, kFrameCount - kFrameCount / 2); | 236 bus->ZeroFramesPartial(kFrameCount / 2, kFrameCount - kFrameCount / 2); |
| 232 for (int i = 0; i < bus->channels(); ++i) { | 237 for (int i = 0; i < bus->channels(); ++i) { |
| 233 SCOPED_TRACE("Last Half Zero"); | 238 SCOPED_TRACE("Last Half Zero"); |
| 234 VerifyValue(bus->channel(i) + kFrameCount / 2, | 239 VerifyArrayIsFilledWithValue(bus->channel(i) + kFrameCount / 2, |
| 235 kFrameCount - kFrameCount / 2, 0); | 240 kFrameCount - kFrameCount / 2, 0); |
| 236 VerifyValue(bus->channel(i), kFrameCount / 2, i + 1); | 241 VerifyArrayIsFilledWithValue(bus->channel(i), kFrameCount / 2, i + 1); |
| 237 } | 242 } |
| 238 EXPECT_FALSE(bus->AreFramesZero()); | 243 EXPECT_FALSE(bus->AreFramesZero()); |
| 239 | 244 |
| 240 // Fill the bus with dummy data. | 245 // Fill the bus with dummy data. |
| 241 for (int i = 0; i < bus->channels(); ++i) | 246 for (int i = 0; i < bus->channels(); ++i) |
| 242 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); | 247 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); |
| 243 | 248 |
| 244 // Zero all the frames of each channel. | 249 // Zero all the frames of each channel. |
| 245 bus->Zero(); | 250 bus->Zero(); |
| 246 for (int i = 0; i < bus->channels(); ++i) { | 251 for (int i = 0; i < bus->channels(); ++i) { |
| 247 SCOPED_TRACE("All Zero"); | 252 SCOPED_TRACE("All Zero"); |
| 248 VerifyValue(bus->channel(i), bus->frames(), 0); | 253 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0); |
| 249 } | 254 } |
| 250 EXPECT_TRUE(bus->AreFramesZero()); | 255 EXPECT_TRUE(bus->AreFramesZero()); |
| 251 } | 256 } |
| 252 | 257 |
| 253 // Each test vector represents two channels of data in the following arbitrary | 258 // Each test vector represents two channels of data in the following arbitrary |
| 254 // layout: <min, zero, max, min, max / 2, min / 2, zero, max, zero, zero>. | 259 // layout: <min, zero, max, min, max / 2, min / 2, zero, max, zero, zero>. |
| 255 static const int kTestVectorSize = 10; | 260 static const int kTestVectorSize = 10; |
| 256 static const uint8_t kTestVectorUint8[kTestVectorSize] = { | 261 static const uint8_t kTestVectorUint8[kTestVectorSize] = { |
| 257 0, -INT8_MIN, UINT8_MAX, | 262 0, -INT8_MIN, UINT8_MAX, |
| 258 0, INT8_MAX / 2 + 128, INT8_MIN / 2 + 128, | 263 0, INT8_MAX / 2 + 128, INT8_MIN / 2 + 128, |
| 259 -INT8_MIN, UINT8_MAX, -INT8_MIN, | 264 -INT8_MIN, UINT8_MAX, -INT8_MIN, |
| 260 -INT8_MIN}; | 265 -INT8_MIN}; |
| 261 static const int16_t kTestVectorInt16[kTestVectorSize] = { | 266 static const int16_t kTestVectorInt16[kTestVectorSize] = { |
| 262 INT16_MIN, 0, INT16_MAX, INT16_MIN, INT16_MAX / 2, | 267 INT16_MIN, 0, INT16_MAX, INT16_MIN, INT16_MAX / 2, |
| 263 INT16_MIN / 2, 0, INT16_MAX, 0, 0}; | 268 INT16_MIN / 2, 0, INT16_MAX, 0, 0}; |
| 264 static const int32_t kTestVectorInt32[kTestVectorSize] = { | 269 static const int32_t kTestVectorInt32[kTestVectorSize] = { |
| 265 INT32_MIN, 0, INT32_MAX, INT32_MIN, INT32_MAX / 2, | 270 INT32_MIN, 0, INT32_MAX, INT32_MIN, INT32_MAX / 2, |
| 266 INT32_MIN / 2, 0, INT32_MAX, 0, 0}; | 271 INT32_MIN / 2, 0, INT32_MAX, 0, 0}; |
| 272 static const float kTestVectorFloat32[kTestVectorSize] = { |
| 273 -1.0f, 0.0f, 1.0f, -1.0f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f}; |
| 267 | 274 |
| 268 // Expected results. | 275 // Expected results. |
| 269 static const int kTestVectorFrames = kTestVectorSize / 2; | 276 static const int kTestVectorFrameCount = kTestVectorSize / 2; |
| 270 static const float kTestVectorResult[][kTestVectorFrames] = { | 277 static const float kTestVectorResult[][kTestVectorFrameCount] = { |
| 271 { -1, 1, 0.5, 0, 0 }, { 0, -1, -0.5, 1, 0 }}; | 278 {-1.0f, 1.0f, 0.5f, 0.0f, 0.0f}, |
| 272 static const int kTestVectorChannels = arraysize(kTestVectorResult); | 279 {0.0f, -1.0f, -0.5f, 1.0f, 0.0f}}; |
| 280 static const int kTestVectorChannelCount = arraysize(kTestVectorResult); |
| 273 | 281 |
| 274 // Verify FromInterleaved() deinterleaves audio in supported formats correctly. | 282 // Verify FromInterleaved() deinterleaves audio in supported formats correctly. |
| 275 TEST_F(AudioBusTest, FromInterleaved) { | 283 TEST_F(AudioBusTest, FromInterleaved) { |
| 276 std::unique_ptr<AudioBus> bus = | 284 std::unique_ptr<AudioBus> bus = |
| 277 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 285 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
| 278 std::unique_ptr<AudioBus> expected = | 286 std::unique_ptr<AudioBus> expected = |
| 279 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 287 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
| 280 for (int ch = 0; ch < kTestVectorChannels; ++ch) { | 288 for (int ch = 0; ch < kTestVectorChannelCount; ++ch) { |
| 281 memcpy(expected->channel(ch), kTestVectorResult[ch], | 289 memcpy(expected->channel(ch), kTestVectorResult[ch], |
| 282 kTestVectorFrames * sizeof(*expected->channel(ch))); | 290 kTestVectorFrameCount * sizeof(*expected->channel(ch))); |
| 283 } | 291 } |
| 292 |
| 293 // Test deprecated version that takes |bytes_per_sample| as an input. |
| 284 { | 294 { |
| 285 SCOPED_TRACE("uint8_t"); | 295 SCOPED_TRACE("uint8_t"); |
| 286 bus->Zero(); | 296 bus->Zero(); |
| 287 bus->FromInterleaved( | 297 bus->FromInterleaved(kTestVectorUint8, kTestVectorFrameCount, |
| 288 kTestVectorUint8, kTestVectorFrames, sizeof(*kTestVectorUint8)); | 298 sizeof(*kTestVectorUint8)); |
| 299 |
| 289 // Biased uint8_t calculations have poor precision, so the epsilon here is | 300 // Biased uint8_t calculations have poor precision, so the epsilon here is |
| 290 // slightly more permissive than int16_t and int32_t calculations. | 301 // slightly more permissive than int16_t and int32_t calculations. |
| 291 VerifyBusWithEpsilon(bus.get(), expected.get(), | 302 VerifyAreEqualWithEpsilon(bus.get(), expected.get(), |
| 292 1.0f / (std::numeric_limits<uint8_t>::max() - 1)); | 303 1.0f / (std::numeric_limits<uint8_t>::max() - 1)); |
| 293 } | 304 } |
| 294 { | 305 { |
| 295 SCOPED_TRACE("int16_t"); | 306 SCOPED_TRACE("int16_t"); |
| 296 bus->Zero(); | 307 bus->Zero(); |
| 297 bus->FromInterleaved( | 308 bus->FromInterleaved(kTestVectorInt16, kTestVectorFrameCount, |
| 298 kTestVectorInt16, kTestVectorFrames, sizeof(*kTestVectorInt16)); | 309 sizeof(*kTestVectorInt16)); |
| 299 VerifyBusWithEpsilon(bus.get(), expected.get(), | 310 VerifyAreEqualWithEpsilon( |
| 300 1.0f / (std::numeric_limits<uint16_t>::max() + 1.0f)); | 311 bus.get(), expected.get(), |
| 312 1.0f / (std::numeric_limits<uint16_t>::max() + 1.0f)); |
| 301 } | 313 } |
| 302 { | 314 { |
| 303 SCOPED_TRACE("int32_t"); | 315 SCOPED_TRACE("int32_t"); |
| 304 bus->Zero(); | 316 bus->Zero(); |
| 305 bus->FromInterleaved( | 317 bus->FromInterleaved(kTestVectorInt32, kTestVectorFrameCount, |
| 306 kTestVectorInt32, kTestVectorFrames, sizeof(*kTestVectorInt32)); | 318 sizeof(*kTestVectorInt32)); |
| 307 VerifyBusWithEpsilon(bus.get(), expected.get(), | 319 VerifyAreEqualWithEpsilon( |
| 308 1.0f / (std::numeric_limits<uint32_t>::max() + 1.0f)); | 320 bus.get(), expected.get(), |
| 321 1.0f / (std::numeric_limits<uint32_t>::max() + 1.0f)); |
| 322 } |
| 323 |
| 324 // Test non-deprecated version that takes SampleTypeTraits as a template |
| 325 // parameter. |
| 326 { |
| 327 SCOPED_TRACE("Linear8BitUnsignedIntSampleTypeTraits"); |
| 328 bus->Zero(); |
| 329 bus->FromInterleaved<Linear8BitUnsignedIntSampleTypeTraits>( |
| 330 kTestVectorUint8, kTestVectorFrameCount); |
| 331 // Biased uint8_t calculations have poor precision, so the epsilon here is |
| 332 // slightly more permissive than int16_t and int32_t calculations. |
| 333 VerifyAreEqualWithEpsilon(bus.get(), expected.get(), |
| 334 1.0f / (std::numeric_limits<uint8_t>::max() - 1)); |
| 335 } |
| 336 { |
| 337 SCOPED_TRACE("Linear16BitSignedIntSampleTypeTraits"); |
| 338 bus->Zero(); |
| 339 bus->FromInterleaved<Linear16BitSignedIntSampleTypeTraits>( |
| 340 kTestVectorInt16, kTestVectorFrameCount); |
| 341 VerifyAreEqualWithEpsilon( |
| 342 bus.get(), expected.get(), |
| 343 1.0f / (std::numeric_limits<uint16_t>::max() + 1.0f)); |
| 344 } |
| 345 { |
| 346 SCOPED_TRACE("Linear32BitSignedIntSampleTypeTraits"); |
| 347 bus->Zero(); |
| 348 bus->FromInterleaved<Linear32BitSignedIntSampleTypeTraits>( |
| 349 kTestVectorInt32, kTestVectorFrameCount); |
| 350 VerifyAreEqualWithEpsilon( |
| 351 bus.get(), expected.get(), |
| 352 1.0f / (std::numeric_limits<uint32_t>::max() + 1.0f)); |
| 353 } |
| 354 { |
| 355 SCOPED_TRACE("Float32SampleTypeTraits"); |
| 356 bus->Zero(); |
| 357 bus->FromInterleaved<Float32SampleTypeTraits>(kTestVectorFloat32, |
| 358 kTestVectorFrameCount); |
| 359 VerifyAreEqual(bus.get(), expected.get()); |
| 309 } | 360 } |
| 310 } | 361 } |
| 311 | 362 |
| 312 // Verify FromInterleavedPartial() deinterleaves audio correctly. | 363 // Verify FromInterleavedPartial() deinterleaves audio correctly. |
| 313 TEST_F(AudioBusTest, FromInterleavedPartial) { | 364 TEST_F(AudioBusTest, FromInterleavedPartial) { |
| 314 // Only deinterleave the middle two frames in each channel. | 365 // Only deinterleave the middle two frames in each channel. |
| 315 static const int kPartialStart = 1; | 366 static const int kPartialStart = 1; |
| 316 static const int kPartialFrames = 2; | 367 static const int kPartialFrames = 2; |
| 317 ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrames); | 368 ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrameCount); |
| 318 | 369 |
| 319 std::unique_ptr<AudioBus> bus = | 370 std::unique_ptr<AudioBus> bus = |
| 320 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 371 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
| 321 std::unique_ptr<AudioBus> expected = | 372 std::unique_ptr<AudioBus> expected = |
| 322 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 373 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
| 323 expected->Zero(); | 374 expected->Zero(); |
| 324 for (int ch = 0; ch < kTestVectorChannels; ++ch) { | 375 for (int ch = 0; ch < kTestVectorChannelCount; ++ch) { |
| 325 memcpy(expected->channel(ch) + kPartialStart, | 376 memcpy(expected->channel(ch) + kPartialStart, |
| 326 kTestVectorResult[ch] + kPartialStart, | 377 kTestVectorResult[ch] + kPartialStart, |
| 327 kPartialFrames * sizeof(*expected->channel(ch))); | 378 kPartialFrames * sizeof(*expected->channel(ch))); |
| 328 } | 379 } |
| 329 | 380 |
| 330 bus->Zero(); | 381 // Test deprecated version that takes |bytes_per_sample| as an input. |
| 331 bus->FromInterleavedPartial( | 382 { |
| 332 kTestVectorInt32 + kPartialStart * bus->channels(), kPartialStart, | 383 SCOPED_TRACE("int32_t"); |
| 333 kPartialFrames, sizeof(*kTestVectorInt32)); | 384 bus->Zero(); |
| 334 VerifyBus(bus.get(), expected.get()); | 385 bus->FromInterleavedPartial( |
| 386 kTestVectorInt32 + kPartialStart * bus->channels(), kPartialStart, |
| 387 kPartialFrames, sizeof(*kTestVectorInt32)); |
| 388 VerifyAreEqual(bus.get(), expected.get()); |
| 389 } |
| 390 |
| 391 // Test non-deprecated version that takes SampleTypeTraits as a template |
| 392 // parameter. |
| 393 { |
| 394 SCOPED_TRACE("Linear32BitSignedIntSampleTypeTraits"); |
| 395 bus->Zero(); |
| 396 bus->FromInterleavedPartial<Linear32BitSignedIntSampleTypeTraits>( |
| 397 kTestVectorInt32 + kPartialStart * bus->channels(), kPartialStart, |
| 398 kPartialFrames); |
| 399 VerifyAreEqual(bus.get(), expected.get()); |
| 400 } |
| 335 } | 401 } |
| 336 | 402 |
| 337 // Verify ToInterleaved() interleaves audio in suported formats correctly. | 403 // Verify ToInterleaved() interleaves audio in suported formats correctly. |
| 338 TEST_F(AudioBusTest, ToInterleaved) { | 404 TEST_F(AudioBusTest, ToInterleaved) { |
| 339 std::unique_ptr<AudioBus> bus = | 405 std::unique_ptr<AudioBus> bus = |
| 340 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 406 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
| 341 // Fill the bus with our test vector. | 407 // Fill the bus with our test vector. |
| 342 for (int ch = 0; ch < bus->channels(); ++ch) { | 408 for (int ch = 0; ch < bus->channels(); ++ch) { |
| 343 memcpy(bus->channel(ch), kTestVectorResult[ch], | 409 memcpy(bus->channel(ch), kTestVectorResult[ch], |
| 344 kTestVectorFrames * sizeof(*bus->channel(ch))); | 410 kTestVectorFrameCount * sizeof(*bus->channel(ch))); |
| 345 } | 411 } |
| 412 |
| 413 // Test deprecated version that takes |bytes_per_sample| as an input. |
| 346 { | 414 { |
| 347 SCOPED_TRACE("uint8_t"); | 415 SCOPED_TRACE("uint8_t"); |
| 348 uint8_t test_array[arraysize(kTestVectorUint8)]; | 416 uint8_t test_array[arraysize(kTestVectorUint8)]; |
| 349 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorUint8), test_array); | 417 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorUint8), test_array); |
| 350 ASSERT_EQ(memcmp( | 418 ASSERT_EQ(0, |
| 351 test_array, kTestVectorUint8, sizeof(kTestVectorUint8)), 0); | 419 memcmp(test_array, kTestVectorUint8, sizeof(kTestVectorUint8))); |
| 352 } | 420 } |
| 353 { | 421 { |
| 354 SCOPED_TRACE("int16_t"); | 422 SCOPED_TRACE("int16_t"); |
| 355 int16_t test_array[arraysize(kTestVectorInt16)]; | 423 int16_t test_array[arraysize(kTestVectorInt16)]; |
| 356 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt16), test_array); | 424 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt16), test_array); |
| 357 ASSERT_EQ(memcmp( | 425 ASSERT_EQ(0, |
| 358 test_array, kTestVectorInt16, sizeof(kTestVectorInt16)), 0); | 426 memcmp(test_array, kTestVectorInt16, sizeof(kTestVectorInt16))); |
| 359 } | 427 } |
| 360 { | 428 { |
| 361 SCOPED_TRACE("int32_t"); | 429 SCOPED_TRACE("int32_t"); |
| 362 int32_t test_array[arraysize(kTestVectorInt32)]; | 430 int32_t test_array[arraysize(kTestVectorInt32)]; |
| 363 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt32), test_array); | 431 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt32), test_array); |
| 364 | 432 |
| 365 // Some compilers get better precision than others on the half-max test, so | 433 // Some compilers get better precision than others on the half-max test, so |
| 366 // let the test pass with an off by one check on the half-max. | 434 // let the test pass with an off by one check on the half-max. |
| 367 int32_t fixed_test_array[arraysize(kTestVectorInt32)]; | 435 int32_t alternative_acceptable_result[arraysize(kTestVectorInt32)]; |
| 368 memcpy(fixed_test_array, kTestVectorInt32, sizeof(kTestVectorInt32)); | 436 memcpy(alternative_acceptable_result, kTestVectorInt32, |
| 369 ASSERT_EQ(fixed_test_array[4], std::numeric_limits<int32_t>::max() / 2); | 437 sizeof(kTestVectorInt32)); |
| 370 fixed_test_array[4]++; | 438 ASSERT_EQ(alternative_acceptable_result[4], |
| 439 std::numeric_limits<int32_t>::max() / 2); |
| 440 alternative_acceptable_result[4]++; |
| 371 | 441 |
| 372 ASSERT_TRUE( | 442 ASSERT_TRUE( |
| 373 memcmp(test_array, kTestVectorInt32, sizeof(kTestVectorInt32)) == 0 || | 443 memcmp(test_array, kTestVectorInt32, sizeof(kTestVectorInt32)) == 0 || |
| 374 memcmp(test_array, fixed_test_array, sizeof(fixed_test_array)) == 0); | 444 memcmp(test_array, alternative_acceptable_result, |
| 445 sizeof(alternative_acceptable_result)) == 0); |
| 446 } |
| 447 |
| 448 // Test non-deprecated version that takes SampleTypeTraits as a template |
| 449 // parameter. |
| 450 { |
| 451 SCOPED_TRACE("Linear8BitUnsignedIntSampleTypeTraits"); |
| 452 uint8_t test_array[arraysize(kTestVectorUint8)]; |
| 453 bus->ToInterleaved<Linear8BitUnsignedIntSampleTypeTraits>(bus->frames(), |
| 454 test_array); |
| 455 ASSERT_EQ(0, |
| 456 memcmp(test_array, kTestVectorUint8, sizeof(kTestVectorUint8))); |
| 457 } |
| 458 { |
| 459 SCOPED_TRACE("Linear16BitSignedIntSampleTypeTraits"); |
| 460 int16_t test_array[arraysize(kTestVectorInt16)]; |
| 461 bus->ToInterleaved<Linear16BitSignedIntSampleTypeTraits>(bus->frames(), |
| 462 test_array); |
| 463 ASSERT_EQ(0, |
| 464 memcmp(test_array, kTestVectorInt16, sizeof(kTestVectorInt16))); |
| 465 } |
| 466 { |
| 467 SCOPED_TRACE("Linear32BitSignedIntSampleTypeTraits"); |
| 468 int32_t test_array[arraysize(kTestVectorInt32)]; |
| 469 bus->ToInterleaved<Linear32BitSignedIntSampleTypeTraits>(bus->frames(), |
| 470 test_array); |
| 471 |
| 472 // Some compilers get better precision than others on the half-max test, so |
| 473 // let the test pass with an off by one check on the half-max. |
| 474 int32_t alternative_acceptable_result[arraysize(kTestVectorInt32)]; |
| 475 memcpy(alternative_acceptable_result, kTestVectorInt32, |
| 476 sizeof(kTestVectorInt32)); |
| 477 ASSERT_EQ(alternative_acceptable_result[4], |
| 478 std::numeric_limits<int32_t>::max() / 2); |
| 479 alternative_acceptable_result[4]++; |
| 480 |
| 481 ASSERT_TRUE( |
| 482 memcmp(test_array, kTestVectorInt32, sizeof(kTestVectorInt32)) == 0 || |
| 483 memcmp(test_array, alternative_acceptable_result, |
| 484 sizeof(alternative_acceptable_result)) == 0); |
| 485 } |
| 486 { |
| 487 SCOPED_TRACE("Float32SampleTypeTraits"); |
| 488 float test_array[arraysize(kTestVectorFloat32)]; |
| 489 bus->ToInterleaved<Float32SampleTypeTraits>(bus->frames(), test_array); |
| 490 ASSERT_EQ( |
| 491 0, memcmp(test_array, kTestVectorFloat32, sizeof(kTestVectorFloat32))); |
| 375 } | 492 } |
| 376 } | 493 } |
| 377 | 494 |
| 378 // Verify ToInterleavedPartial() interleaves audio correctly. | 495 // Verify ToInterleavedPartial() interleaves audio correctly. |
| 379 TEST_F(AudioBusTest, ToInterleavedPartial) { | 496 TEST_F(AudioBusTest, ToInterleavedPartial) { |
| 380 // Only interleave the middle two frames in each channel. | 497 // Only interleave the middle two frames in each channel. |
| 381 static const int kPartialStart = 1; | 498 static const int kPartialStart = 1; |
| 382 static const int kPartialFrames = 2; | 499 static const int kPartialFrames = 2; |
| 383 ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrames); | 500 ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrameCount); |
| 384 | 501 |
| 385 std::unique_ptr<AudioBus> expected = | 502 std::unique_ptr<AudioBus> expected = |
| 386 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 503 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
| 387 for (int ch = 0; ch < kTestVectorChannels; ++ch) { | 504 for (int ch = 0; ch < kTestVectorChannelCount; ++ch) { |
| 388 memcpy(expected->channel(ch), kTestVectorResult[ch], | 505 memcpy(expected->channel(ch), kTestVectorResult[ch], |
| 389 kTestVectorFrames * sizeof(*expected->channel(ch))); | 506 kTestVectorFrameCount * sizeof(*expected->channel(ch))); |
| 390 } | 507 } |
| 391 | 508 |
| 392 int16_t test_array[arraysize(kTestVectorInt16)]; | 509 // Test deprecated version that takes |bytes_per_sample| as an input. |
| 393 expected->ToInterleavedPartial( | 510 { |
| 394 kPartialStart, kPartialFrames, sizeof(*kTestVectorInt16), test_array); | 511 SCOPED_TRACE("int16_t"); |
| 395 ASSERT_EQ(memcmp( | 512 int16_t test_array[arraysize(kTestVectorInt16)]; |
| 396 test_array, kTestVectorInt16 + kPartialStart * kTestVectorChannels, | 513 expected->ToInterleavedPartial(kPartialStart, kPartialFrames, |
| 397 kPartialFrames * sizeof(*kTestVectorInt16) * kTestVectorChannels), 0); | 514 sizeof(*kTestVectorInt16), test_array); |
| 515 ASSERT_EQ(0, memcmp(test_array, kTestVectorInt16 + |
| 516 kPartialStart * kTestVectorChannelCount, |
| 517 kPartialFrames * sizeof(*kTestVectorInt16) * |
| 518 kTestVectorChannelCount)); |
| 519 } |
| 520 |
| 521 // Test non-deprecated version that takes SampleTypeTraits as a template |
| 522 // parameter. |
| 523 { |
| 524 SCOPED_TRACE("Float32SampleTypeTraits"); |
| 525 float test_array[arraysize(kTestVectorFloat32)]; |
| 526 expected->ToInterleavedPartial<Float32SampleTypeTraits>( |
| 527 kPartialStart, kPartialFrames, test_array); |
| 528 ASSERT_EQ(0, memcmp(test_array, kTestVectorFloat32 + |
| 529 kPartialStart * kTestVectorChannelCount, |
| 530 kPartialFrames * sizeof(*kTestVectorFloat32) * |
| 531 kTestVectorChannelCount)); |
| 532 } |
| 398 } | 533 } |
| 399 | 534 |
| 400 TEST_F(AudioBusTest, Scale) { | 535 TEST_F(AudioBusTest, Scale) { |
| 401 std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); | 536 std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); |
| 402 | 537 |
| 403 // Fill the bus with dummy data. | 538 // Fill the bus with dummy data. |
| 404 static const float kFillValue = 1; | 539 static const float kFillValue = 1; |
| 405 for (int i = 0; i < bus->channels(); ++i) | 540 for (int i = 0; i < bus->channels(); ++i) |
| 406 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), kFillValue); | 541 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), kFillValue); |
| 407 | 542 |
| 408 // Adjust by an invalid volume and ensure volume is unchanged. | 543 // Adjust by an invalid volume and ensure volume is unchanged. |
| 409 bus->Scale(-1); | 544 bus->Scale(-1); |
| 410 for (int i = 0; i < bus->channels(); ++i) { | 545 for (int i = 0; i < bus->channels(); ++i) { |
| 411 SCOPED_TRACE("Invalid Scale"); | 546 SCOPED_TRACE("Invalid Scale"); |
| 412 VerifyValue(bus->channel(i), bus->frames(), kFillValue); | 547 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), kFillValue); |
| 413 } | 548 } |
| 414 | 549 |
| 415 // Verify correct volume adjustment. | 550 // Verify correct volume adjustment. |
| 416 static const float kVolume = 0.5; | 551 static const float kVolume = 0.5; |
| 417 bus->Scale(kVolume); | 552 bus->Scale(kVolume); |
| 418 for (int i = 0; i < bus->channels(); ++i) { | 553 for (int i = 0; i < bus->channels(); ++i) { |
| 419 SCOPED_TRACE("Half Scale"); | 554 SCOPED_TRACE("Half Scale"); |
| 420 VerifyValue(bus->channel(i), bus->frames(), kFillValue * kVolume); | 555 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), |
| 556 kFillValue * kVolume); |
| 421 } | 557 } |
| 422 | 558 |
| 423 // Verify zero volume case. | 559 // Verify zero volume case. |
| 424 bus->Scale(0); | 560 bus->Scale(0); |
| 425 for (int i = 0; i < bus->channels(); ++i) { | 561 for (int i = 0; i < bus->channels(); ++i) { |
| 426 SCOPED_TRACE("Zero Scale"); | 562 SCOPED_TRACE("Zero Scale"); |
| 427 VerifyValue(bus->channel(i), bus->frames(), 0); | 563 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0); |
| 428 } | 564 } |
| 429 } | 565 } |
| 430 | 566 |
| 431 } // namespace media | 567 } // namespace media |
| OLD | NEW |