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 |