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)); |
| 58 |
57 if (epsilon == 0) { | 59 if (epsilon == 0) { |
58 ASSERT_FLOAT_EQ(expected->channel(ch)[i], result->channel(ch)[i]); | 60 ASSERT_FLOAT_EQ(expected->channel(ch)[i], result->channel(ch)[i]); |
59 } else { | 61 } else { |
60 ASSERT_NEAR(expected->channel(ch)[i], result->channel(ch)[i], | 62 ASSERT_NEAR(expected->channel(ch)[i], result->channel(ch)[i], |
61 epsilon); | 63 epsilon); |
62 } | 64 } |
63 } | 65 } |
64 } | 66 } |
65 } | 67 } |
66 | 68 |
67 // Verify values for each channel in |result| against |expected|. | 69 // Verify values for each channel in |result| against |expected|. |
68 void VerifyBus(const AudioBus* result, const AudioBus* expected) { | 70 void VerifyAreEqual(const AudioBus* result, const AudioBus* expected) { |
69 VerifyBusWithEpsilon(result, expected, 0); | 71 VerifyAreEqualWithEpsilon(result, expected, 0); |
70 } | 72 } |
71 | 73 |
72 // Read and write to the full extent of the allocated channel data. Also test | 74 // 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 | 75 // 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). | 76 // is 16-byte aligned as advertised (see kChannelAlignment in audio_bus.h). |
75 void VerifyChannelData(AudioBus* bus) { | 77 void VerifyReadWriteAndAlignment(AudioBus* bus) { |
76 for (int i = 0; i < bus->channels(); ++i) { | 78 for (int i = 0; i < bus->channels(); ++i) { |
| 79 // Verify that the address returned by channel(i) is a multiple of |
| 80 // AudioBus::kChannelAlignment. |
77 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>( | 81 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>( |
78 bus->channel(i)) & (AudioBus::kChannelAlignment - 1)); | 82 bus->channel(i)) & (AudioBus::kChannelAlignment - 1)); |
| 83 |
| 84 // Write into the channel buffer. |
79 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i); | 85 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i); |
80 } | 86 } |
81 | 87 |
82 for (int i = 0; i < bus->channels(); ++i) | 88 for (int i = 0; i < bus->channels(); ++i) |
83 VerifyValue(bus->channel(i), bus->frames(), i); | 89 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), i); |
84 | 90 |
85 bus->Zero(); | 91 bus->Zero(); |
86 for (int i = 0; i < bus->channels(); ++i) | 92 for (int i = 0; i < bus->channels(); ++i) |
87 VerifyValue(bus->channel(i), bus->frames(), 0); | 93 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0); |
88 } | 94 } |
89 | 95 |
90 // Verify copying to and from |bus1| and |bus2|. | 96 // Verify copying to and from |bus1| and |bus2|. |
91 void CopyTest(AudioBus* bus1, AudioBus* bus2) { | 97 void CopyTest(AudioBus* bus1, AudioBus* bus2) { |
92 // Fill |bus1| with dummy data. | 98 // Fill |bus1| with dummy data. |
93 for (int i = 0; i < bus1->channels(); ++i) | 99 for (int i = 0; i < bus1->channels(); ++i) |
94 std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i); | 100 std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i); |
95 | 101 |
96 // Verify copy from |bus1| to |bus2|. | 102 // Verify copy from |bus1| to |bus2|. |
97 bus2->Zero(); | 103 bus2->Zero(); |
98 bus1->CopyTo(bus2); | 104 bus1->CopyTo(bus2); |
99 VerifyBus(bus1, bus2); | 105 VerifyAreEqual(bus1, bus2); |
100 | 106 |
101 // Verify copy from |bus2| to |bus1|. | 107 // Verify copy from |bus2| to |bus1|. |
102 bus1->Zero(); | 108 bus1->Zero(); |
103 bus2->CopyTo(bus1); | 109 bus2->CopyTo(bus1); |
104 VerifyBus(bus2, bus1); | 110 VerifyAreEqual(bus2, bus1); |
105 } | 111 } |
106 | 112 |
107 protected: | 113 protected: |
108 std::vector<float*> data_; | 114 std::vector<float*> data_; |
109 | 115 |
110 DISALLOW_COPY_AND_ASSIGN(AudioBusTest); | 116 DISALLOW_COPY_AND_ASSIGN(AudioBusTest); |
111 }; | 117 }; |
112 | 118 |
113 // Verify basic Create(...) method works as advertised. | 119 // Verify basic Create(...) method works as advertised. |
114 TEST_F(AudioBusTest, Create) { | 120 TEST_F(AudioBusTest, Create) { |
115 std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); | 121 std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); |
116 VerifyParams(bus.get()); | 122 VerifyChannelAndFrameCount(bus.get()); |
117 VerifyChannelData(bus.get()); | 123 VerifyReadWriteAndAlignment(bus.get()); |
118 } | 124 } |
119 | 125 |
120 // Verify Create(...) using AudioParameters works as advertised. | 126 // Verify Create(...) using AudioParameters works as advertised. |
121 TEST_F(AudioBusTest, CreateUsingAudioParameters) { | 127 TEST_F(AudioBusTest, CreateUsingAudioParameters) { |
122 std::unique_ptr<AudioBus> bus = AudioBus::Create( | 128 std::unique_ptr<AudioBus> bus = AudioBus::Create( |
123 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, | 129 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, |
124 kSampleRate, 32, kFrameCount)); | 130 kSampleRate, 32, kFrameCount)); |
125 VerifyParams(bus.get()); | 131 VerifyChannelAndFrameCount(bus.get()); |
126 VerifyChannelData(bus.get()); | 132 VerifyReadWriteAndAlignment(bus.get()); |
127 } | 133 } |
128 | 134 |
129 // Verify an AudioBus created via wrapping a vector works as advertised. | 135 // Verify an AudioBus created via wrapping a vector works as advertised. |
130 TEST_F(AudioBusTest, WrapVector) { | 136 TEST_F(AudioBusTest, WrapVector) { |
131 data_.reserve(kChannels); | 137 data_.reserve(kChannels); |
132 for (int i = 0; i < kChannels; ++i) { | 138 for (int i = 0; i < kChannels; ++i) { |
133 data_.push_back(static_cast<float*>(base::AlignedAlloc( | 139 data_.push_back(static_cast<float*>(base::AlignedAlloc( |
134 sizeof(*data_[i]) * kFrameCount, AudioBus::kChannelAlignment))); | 140 sizeof(*data_[i]) * kFrameCount, AudioBus::kChannelAlignment))); |
135 } | 141 } |
136 | 142 |
137 std::unique_ptr<AudioBus> bus = AudioBus::WrapVector(kFrameCount, data_); | 143 std::unique_ptr<AudioBus> bus = AudioBus::WrapVector(kFrameCount, data_); |
138 VerifyParams(bus.get()); | 144 VerifyChannelAndFrameCount(bus.get()); |
139 VerifyChannelData(bus.get()); | 145 VerifyReadWriteAndAlignment(bus.get()); |
140 } | 146 } |
141 | 147 |
142 // Verify an AudioBus created via wrapping a memory block works as advertised. | 148 // Verify an AudioBus created via wrapping a memory block works as advertised. |
143 TEST_F(AudioBusTest, WrapMemory) { | 149 TEST_F(AudioBusTest, WrapMemory) { |
144 AudioParameters params( | 150 AudioParameters params( |
145 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32, | 151 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32, |
146 kFrameCount); | 152 kFrameCount); |
147 int data_size = AudioBus::CalculateMemorySize(params); | 153 int data_size = AudioBus::CalculateMemorySize(params); |
148 std::unique_ptr<float, base::AlignedFreeDeleter> data(static_cast<float*>( | 154 std::unique_ptr<float, base::AlignedFreeDeleter> data(static_cast<float*>( |
149 base::AlignedAlloc(data_size, AudioBus::kChannelAlignment))); | 155 base::AlignedAlloc(data_size, AudioBus::kChannelAlignment))); |
150 | 156 |
151 // Fill the memory with a test value we can check for after wrapping. | 157 // Fill the memory with a test value we can check for after wrapping. |
152 static const float kTestValue = 3; | 158 static const float kTestValue = 3; |
153 std::fill( | 159 std::fill( |
154 data.get(), data.get() + data_size / sizeof(*data.get()), kTestValue); | 160 data.get(), data.get() + data_size / sizeof(*data.get()), kTestValue); |
155 | 161 |
156 std::unique_ptr<AudioBus> bus = AudioBus::WrapMemory(params, data.get()); | 162 std::unique_ptr<AudioBus> bus = AudioBus::WrapMemory(params, data.get()); |
157 // Verify the test value we filled prior to wrapping. | 163 // Verify the test value we filled prior to wrapping. |
158 for (int i = 0; i < bus->channels(); ++i) | 164 for (int i = 0; i < bus->channels(); ++i) |
159 VerifyValue(bus->channel(i), bus->frames(), kTestValue); | 165 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), kTestValue); |
160 VerifyParams(bus.get()); | 166 VerifyChannelAndFrameCount(bus.get()); |
161 VerifyChannelData(bus.get()); | 167 VerifyReadWriteAndAlignment(bus.get()); |
162 | 168 |
163 // Verify the channel vectors lie within the provided memory block. | 169 // Verify the channel vectors lie within the provided memory block. |
164 EXPECT_GE(bus->channel(0), data.get()); | 170 EXPECT_GE(bus->channel(0), data.get()); |
165 EXPECT_LT(bus->channel(bus->channels() - 1) + bus->frames(), | 171 EXPECT_LT(bus->channel(bus->channels() - 1) + bus->frames(), |
166 data.get() + data_size / sizeof(*data.get())); | 172 data.get() + data_size / sizeof(*data.get())); |
167 } | 173 } |
168 | 174 |
169 // Simulate a shared memory transfer and verify results. | 175 // Simulate a shared memory transfer and verify results. |
170 TEST_F(AudioBusTest, CopyTo) { | 176 TEST_F(AudioBusTest, CopyTo) { |
171 // Create one bus with AudioParameters and the other through direct values to | 177 // 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 | 216 |
211 // Fill the bus with dummy data. | 217 // Fill the bus with dummy data. |
212 for (int i = 0; i < bus->channels(); ++i) | 218 for (int i = 0; i < bus->channels(); ++i) |
213 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); | 219 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); |
214 EXPECT_FALSE(bus->AreFramesZero()); | 220 EXPECT_FALSE(bus->AreFramesZero()); |
215 | 221 |
216 // Zero first half the frames of each channel. | 222 // Zero first half the frames of each channel. |
217 bus->ZeroFrames(kFrameCount / 2); | 223 bus->ZeroFrames(kFrameCount / 2); |
218 for (int i = 0; i < bus->channels(); ++i) { | 224 for (int i = 0; i < bus->channels(); ++i) { |
219 SCOPED_TRACE("First Half Zero"); | 225 SCOPED_TRACE("First Half Zero"); |
220 VerifyValue(bus->channel(i), kFrameCount / 2, 0); | 226 VerifyArrayIsFilledWithValue(bus->channel(i), kFrameCount / 2, 0); |
221 VerifyValue(bus->channel(i) + kFrameCount / 2, | 227 VerifyArrayIsFilledWithValue(bus->channel(i) + kFrameCount / 2, |
222 kFrameCount - kFrameCount / 2, i + 1); | 228 kFrameCount - kFrameCount / 2, i + 1); |
223 } | 229 } |
224 EXPECT_FALSE(bus->AreFramesZero()); | 230 EXPECT_FALSE(bus->AreFramesZero()); |
225 | 231 |
226 // Fill the bus with dummy data. | 232 // Fill the bus with dummy data. |
227 for (int i = 0; i < bus->channels(); ++i) | 233 for (int i = 0; i < bus->channels(); ++i) |
228 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); | 234 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); |
229 | 235 |
230 // Zero the last half of the frames. | 236 // Zero the last half of the frames. |
231 bus->ZeroFramesPartial(kFrameCount / 2, kFrameCount - kFrameCount / 2); | 237 bus->ZeroFramesPartial(kFrameCount / 2, kFrameCount - kFrameCount / 2); |
232 for (int i = 0; i < bus->channels(); ++i) { | 238 for (int i = 0; i < bus->channels(); ++i) { |
233 SCOPED_TRACE("Last Half Zero"); | 239 SCOPED_TRACE("Last Half Zero"); |
234 VerifyValue(bus->channel(i) + kFrameCount / 2, | 240 VerifyArrayIsFilledWithValue(bus->channel(i) + kFrameCount / 2, |
235 kFrameCount - kFrameCount / 2, 0); | 241 kFrameCount - kFrameCount / 2, 0); |
236 VerifyValue(bus->channel(i), kFrameCount / 2, i + 1); | 242 VerifyArrayIsFilledWithValue(bus->channel(i), kFrameCount / 2, i + 1); |
237 } | 243 } |
238 EXPECT_FALSE(bus->AreFramesZero()); | 244 EXPECT_FALSE(bus->AreFramesZero()); |
239 | 245 |
240 // Fill the bus with dummy data. | 246 // Fill the bus with dummy data. |
241 for (int i = 0; i < bus->channels(); ++i) | 247 for (int i = 0; i < bus->channels(); ++i) |
242 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); | 248 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); |
243 | 249 |
244 // Zero all the frames of each channel. | 250 // Zero all the frames of each channel. |
245 bus->Zero(); | 251 bus->Zero(); |
246 for (int i = 0; i < bus->channels(); ++i) { | 252 for (int i = 0; i < bus->channels(); ++i) { |
247 SCOPED_TRACE("All Zero"); | 253 SCOPED_TRACE("All Zero"); |
248 VerifyValue(bus->channel(i), bus->frames(), 0); | 254 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0); |
249 } | 255 } |
250 EXPECT_TRUE(bus->AreFramesZero()); | 256 EXPECT_TRUE(bus->AreFramesZero()); |
251 } | 257 } |
252 | 258 |
253 // Each test vector represents two channels of data in the following arbitrary | 259 // 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>. | 260 // layout: <min, zero, max, min, max / 2, min / 2, zero, max, zero, zero>. |
255 static const int kTestVectorSize = 10; | 261 static const int kTestVectorSize = 10; |
256 static const uint8_t kTestVectorUint8[kTestVectorSize] = { | 262 static const uint8_t kTestVectorUint8[kTestVectorSize] = { |
257 0, -INT8_MIN, UINT8_MAX, | 263 0, -INT8_MIN, UINT8_MAX, |
258 0, INT8_MAX / 2 + 128, INT8_MIN / 2 + 128, | 264 0, INT8_MAX / 2 + 128, INT8_MIN / 2 + 128, |
259 -INT8_MIN, UINT8_MAX, -INT8_MIN, | 265 -INT8_MIN, UINT8_MAX, -INT8_MIN, |
260 -INT8_MIN}; | 266 -INT8_MIN}; |
261 static const int16_t kTestVectorInt16[kTestVectorSize] = { | 267 static const int16_t kTestVectorInt16[kTestVectorSize] = { |
262 INT16_MIN, 0, INT16_MAX, INT16_MIN, INT16_MAX / 2, | 268 INT16_MIN, 0, INT16_MAX, INT16_MIN, INT16_MAX / 2, |
263 INT16_MIN / 2, 0, INT16_MAX, 0, 0}; | 269 INT16_MIN / 2, 0, INT16_MAX, 0, 0}; |
264 static const int32_t kTestVectorInt32[kTestVectorSize] = { | 270 static const int32_t kTestVectorInt32[kTestVectorSize] = { |
265 INT32_MIN, 0, INT32_MAX, INT32_MIN, INT32_MAX / 2, | 271 INT32_MIN, 0, INT32_MAX, INT32_MIN, INT32_MAX / 2, |
266 INT32_MIN / 2, 0, INT32_MAX, 0, 0}; | 272 INT32_MIN / 2, 0, INT32_MAX, 0, 0}; |
| 273 static const float kTestVectorFloat32[kTestVectorSize] = { |
| 274 -1.0f, 0.0f, 1.0f, -1.0f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f}; |
267 | 275 |
268 // Expected results. | 276 // Expected results. |
269 static const int kTestVectorFrames = kTestVectorSize / 2; | 277 static const int kTestVectorFrameCount = kTestVectorSize / 2; |
270 static const float kTestVectorResult[][kTestVectorFrames] = { | 278 static const float kTestVectorResult[][kTestVectorFrameCount] = { |
271 { -1, 1, 0.5, 0, 0 }, { 0, -1, -0.5, 1, 0 }}; | 279 {-1.0f, 1.0f, 0.5f, 0.0f, 0.0f}, |
272 static const int kTestVectorChannels = arraysize(kTestVectorResult); | 280 {0.0f, -1.0f, -0.5f, 1.0f, 0.0f}}; |
| 281 static const int kTestVectorChannelCount = arraysize(kTestVectorResult); |
273 | 282 |
274 // Verify FromInterleaved() deinterleaves audio in supported formats correctly. | 283 // Verify FromInterleaved() deinterleaves audio in supported formats correctly. |
275 TEST_F(AudioBusTest, FromInterleaved) { | 284 TEST_F(AudioBusTest, FromInterleaved) { |
276 std::unique_ptr<AudioBus> bus = | 285 std::unique_ptr<AudioBus> bus = |
277 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 286 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
278 std::unique_ptr<AudioBus> expected = | 287 std::unique_ptr<AudioBus> expected = |
279 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 288 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
280 for (int ch = 0; ch < kTestVectorChannels; ++ch) { | 289 for (int ch = 0; ch < kTestVectorChannelCount; ++ch) { |
281 memcpy(expected->channel(ch), kTestVectorResult[ch], | 290 memcpy(expected->channel(ch), kTestVectorResult[ch], |
282 kTestVectorFrames * sizeof(*expected->channel(ch))); | 291 kTestVectorFrameCount * sizeof(*expected->channel(ch))); |
283 } | 292 } |
| 293 |
| 294 // Test deprecated version that takes |bytes_per_sample| as an input. |
284 { | 295 { |
285 SCOPED_TRACE("uint8_t"); | 296 SCOPED_TRACE("uint8_t"); |
286 bus->Zero(); | 297 bus->Zero(); |
287 bus->FromInterleaved( | 298 bus->FromInterleaved(kTestVectorUint8, kTestVectorFrameCount, |
288 kTestVectorUint8, kTestVectorFrames, sizeof(*kTestVectorUint8)); | 299 sizeof(*kTestVectorUint8)); |
| 300 |
289 // Biased uint8_t calculations have poor precision, so the epsilon here is | 301 // Biased uint8_t calculations have poor precision, so the epsilon here is |
290 // slightly more permissive than int16_t and int32_t calculations. | 302 // slightly more permissive than int16_t and int32_t calculations. |
291 VerifyBusWithEpsilon(bus.get(), expected.get(), | 303 VerifyAreEqualWithEpsilon(bus.get(), expected.get(), |
292 1.0f / (std::numeric_limits<uint8_t>::max() - 1)); | 304 1.0f / (std::numeric_limits<uint8_t>::max() - 1)); |
293 } | 305 } |
294 { | 306 { |
295 SCOPED_TRACE("int16_t"); | 307 SCOPED_TRACE("int16_t"); |
296 bus->Zero(); | 308 bus->Zero(); |
297 bus->FromInterleaved( | 309 bus->FromInterleaved(kTestVectorInt16, kTestVectorFrameCount, |
298 kTestVectorInt16, kTestVectorFrames, sizeof(*kTestVectorInt16)); | 310 sizeof(*kTestVectorInt16)); |
299 VerifyBusWithEpsilon(bus.get(), expected.get(), | 311 VerifyAreEqualWithEpsilon( |
300 1.0f / (std::numeric_limits<uint16_t>::max() + 1.0f)); | 312 bus.get(), expected.get(), |
| 313 1.0f / (std::numeric_limits<uint16_t>::max() + 1.0f)); |
301 } | 314 } |
302 { | 315 { |
303 SCOPED_TRACE("int32_t"); | 316 SCOPED_TRACE("int32_t"); |
304 bus->Zero(); | 317 bus->Zero(); |
305 bus->FromInterleaved( | 318 bus->FromInterleaved(kTestVectorInt32, kTestVectorFrameCount, |
306 kTestVectorInt32, kTestVectorFrames, sizeof(*kTestVectorInt32)); | 319 sizeof(*kTestVectorInt32)); |
307 VerifyBusWithEpsilon(bus.get(), expected.get(), | 320 |
308 1.0f / (std::numeric_limits<uint32_t>::max() + 1.0f)); | 321 VerifyAreEqualWithEpsilon( |
| 322 bus.get(), expected.get(), |
| 323 1.0f / (std::numeric_limits<uint32_t>::max() + 1.0f)); |
| 324 } |
| 325 |
| 326 // Test non-deprecated version that takes SampleTypeTraits as a template |
| 327 // parameter. |
| 328 { |
| 329 SCOPED_TRACE("UnsignedInt8SampleTypeTraits"); |
| 330 bus->Zero(); |
| 331 bus->FromInterleaved<UnsignedInt8SampleTypeTraits>(kTestVectorUint8, |
| 332 kTestVectorFrameCount); |
| 333 // Biased uint8_t calculations have poor precision, so the epsilon here is |
| 334 // slightly more permissive than int16_t and int32_t calculations. |
| 335 VerifyAreEqualWithEpsilon(bus.get(), expected.get(), |
| 336 1.0f / (std::numeric_limits<uint8_t>::max() - 1)); |
| 337 } |
| 338 { |
| 339 SCOPED_TRACE("SignedInt16SampleTypeTraits"); |
| 340 bus->Zero(); |
| 341 bus->FromInterleaved<SignedInt16SampleTypeTraits>(kTestVectorInt16, |
| 342 kTestVectorFrameCount); |
| 343 VerifyAreEqualWithEpsilon( |
| 344 bus.get(), expected.get(), |
| 345 1.0f / (std::numeric_limits<uint16_t>::max() + 1.0f)); |
| 346 } |
| 347 { |
| 348 SCOPED_TRACE("SignedInt32SampleTypeTraits"); |
| 349 bus->Zero(); |
| 350 bus->FromInterleaved<SignedInt32SampleTypeTraits>(kTestVectorInt32, |
| 351 kTestVectorFrameCount); |
| 352 VerifyAreEqualWithEpsilon( |
| 353 bus.get(), expected.get(), |
| 354 1.0f / (std::numeric_limits<uint32_t>::max() + 1.0f)); |
| 355 } |
| 356 { |
| 357 SCOPED_TRACE("Float32SampleTypeTraits"); |
| 358 bus->Zero(); |
| 359 bus->FromInterleaved<Float32SampleTypeTraits>(kTestVectorFloat32, |
| 360 kTestVectorFrameCount); |
| 361 VerifyAreEqual(bus.get(), expected.get()); |
309 } | 362 } |
310 } | 363 } |
311 | 364 |
312 // Verify FromInterleavedPartial() deinterleaves audio correctly. | 365 // Verify FromInterleavedPartial() deinterleaves audio correctly. |
313 TEST_F(AudioBusTest, FromInterleavedPartial) { | 366 TEST_F(AudioBusTest, FromInterleavedPartial) { |
314 // Only deinterleave the middle two frames in each channel. | 367 // Only deinterleave the middle two frames in each channel. |
315 static const int kPartialStart = 1; | 368 static const int kPartialStart = 1; |
316 static const int kPartialFrames = 2; | 369 static const int kPartialFrames = 2; |
317 ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrames); | 370 ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrameCount); |
318 | 371 |
319 std::unique_ptr<AudioBus> bus = | 372 std::unique_ptr<AudioBus> bus = |
320 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 373 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
321 std::unique_ptr<AudioBus> expected = | 374 std::unique_ptr<AudioBus> expected = |
322 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 375 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
323 expected->Zero(); | 376 expected->Zero(); |
324 for (int ch = 0; ch < kTestVectorChannels; ++ch) { | 377 for (int ch = 0; ch < kTestVectorChannelCount; ++ch) { |
325 memcpy(expected->channel(ch) + kPartialStart, | 378 memcpy(expected->channel(ch) + kPartialStart, |
326 kTestVectorResult[ch] + kPartialStart, | 379 kTestVectorResult[ch] + kPartialStart, |
327 kPartialFrames * sizeof(*expected->channel(ch))); | 380 kPartialFrames * sizeof(*expected->channel(ch))); |
328 } | 381 } |
329 | 382 |
330 bus->Zero(); | 383 // Test deprecated version that takes |bytes_per_sample| as an input. |
331 bus->FromInterleavedPartial( | 384 { |
332 kTestVectorInt32 + kPartialStart * bus->channels(), kPartialStart, | 385 SCOPED_TRACE("int32_t"); |
333 kPartialFrames, sizeof(*kTestVectorInt32)); | 386 bus->Zero(); |
334 VerifyBus(bus.get(), expected.get()); | 387 bus->FromInterleavedPartial( |
| 388 kTestVectorInt32 + kPartialStart * bus->channels(), kPartialStart, |
| 389 kPartialFrames, sizeof(*kTestVectorInt32)); |
| 390 VerifyAreEqual(bus.get(), expected.get()); |
| 391 } |
| 392 |
| 393 // Test non-deprecated version that takes SampleTypeTraits as a template |
| 394 // parameter. |
| 395 { |
| 396 SCOPED_TRACE("SignedInt32SampleTypeTraits"); |
| 397 bus->Zero(); |
| 398 bus->FromInterleavedPartial<SignedInt32SampleTypeTraits>( |
| 399 kTestVectorInt32 + kPartialStart * bus->channels(), kPartialStart, |
| 400 kPartialFrames); |
| 401 VerifyAreEqual(bus.get(), expected.get()); |
| 402 } |
335 } | 403 } |
336 | 404 |
337 // Verify ToInterleaved() interleaves audio in suported formats correctly. | 405 // Verify ToInterleaved() interleaves audio in suported formats correctly. |
338 TEST_F(AudioBusTest, ToInterleaved) { | 406 TEST_F(AudioBusTest, ToInterleaved) { |
339 std::unique_ptr<AudioBus> bus = | 407 std::unique_ptr<AudioBus> bus = |
340 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 408 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
341 // Fill the bus with our test vector. | 409 // Fill the bus with our test vector. |
342 for (int ch = 0; ch < bus->channels(); ++ch) { | 410 for (int ch = 0; ch < bus->channels(); ++ch) { |
343 memcpy(bus->channel(ch), kTestVectorResult[ch], | 411 memcpy(bus->channel(ch), kTestVectorResult[ch], |
344 kTestVectorFrames * sizeof(*bus->channel(ch))); | 412 kTestVectorFrameCount * sizeof(*bus->channel(ch))); |
345 } | 413 } |
| 414 |
| 415 // Test deprecated version that takes |bytes_per_sample| as an input. |
346 { | 416 { |
347 SCOPED_TRACE("uint8_t"); | 417 SCOPED_TRACE("uint8_t"); |
348 uint8_t test_array[arraysize(kTestVectorUint8)]; | 418 uint8_t test_array[arraysize(kTestVectorUint8)]; |
349 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorUint8), test_array); | 419 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorUint8), test_array); |
350 ASSERT_EQ(memcmp( | 420 ASSERT_EQ(0, |
351 test_array, kTestVectorUint8, sizeof(kTestVectorUint8)), 0); | 421 memcmp(test_array, kTestVectorUint8, sizeof(kTestVectorUint8))); |
352 } | 422 } |
353 { | 423 { |
354 SCOPED_TRACE("int16_t"); | 424 SCOPED_TRACE("int16_t"); |
355 int16_t test_array[arraysize(kTestVectorInt16)]; | 425 int16_t test_array[arraysize(kTestVectorInt16)]; |
356 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt16), test_array); | 426 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt16), test_array); |
357 ASSERT_EQ(memcmp( | 427 ASSERT_EQ(0, |
358 test_array, kTestVectorInt16, sizeof(kTestVectorInt16)), 0); | 428 memcmp(test_array, kTestVectorInt16, sizeof(kTestVectorInt16))); |
359 } | 429 } |
360 { | 430 { |
361 SCOPED_TRACE("int32_t"); | 431 SCOPED_TRACE("int32_t"); |
362 int32_t test_array[arraysize(kTestVectorInt32)]; | 432 int32_t test_array[arraysize(kTestVectorInt32)]; |
363 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt32), test_array); | 433 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt32), test_array); |
364 | 434 |
365 // Some compilers get better precision than others on the half-max test, so | 435 // 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. | 436 // let the test pass with an off by one check on the half-max. |
367 int32_t fixed_test_array[arraysize(kTestVectorInt32)]; | 437 int32_t alternative_acceptable_result[arraysize(kTestVectorInt32)]; |
368 memcpy(fixed_test_array, kTestVectorInt32, sizeof(kTestVectorInt32)); | 438 memcpy(alternative_acceptable_result, kTestVectorInt32, |
369 ASSERT_EQ(fixed_test_array[4], std::numeric_limits<int32_t>::max() / 2); | 439 sizeof(kTestVectorInt32)); |
370 fixed_test_array[4]++; | 440 ASSERT_EQ(alternative_acceptable_result[4], |
| 441 std::numeric_limits<int32_t>::max() / 2); |
| 442 alternative_acceptable_result[4]++; |
371 | 443 |
372 ASSERT_TRUE( | 444 ASSERT_TRUE( |
373 memcmp(test_array, kTestVectorInt32, sizeof(kTestVectorInt32)) == 0 || | 445 memcmp(test_array, kTestVectorInt32, sizeof(kTestVectorInt32)) == 0 || |
374 memcmp(test_array, fixed_test_array, sizeof(fixed_test_array)) == 0); | 446 memcmp(test_array, alternative_acceptable_result, |
| 447 sizeof(alternative_acceptable_result)) == 0); |
| 448 } |
| 449 |
| 450 // Test non-deprecated version that takes SampleTypeTraits as a template |
| 451 // parameter. |
| 452 { |
| 453 SCOPED_TRACE("UnsignedInt8SampleTypeTraits"); |
| 454 uint8_t test_array[arraysize(kTestVectorUint8)]; |
| 455 bus->ToInterleaved<UnsignedInt8SampleTypeTraits>(bus->frames(), test_array); |
| 456 ASSERT_EQ(0, |
| 457 memcmp(test_array, kTestVectorUint8, sizeof(kTestVectorUint8))); |
| 458 } |
| 459 { |
| 460 SCOPED_TRACE("SignedInt16SampleTypeTraits"); |
| 461 int16_t test_array[arraysize(kTestVectorInt16)]; |
| 462 bus->ToInterleaved<SignedInt16SampleTypeTraits>(bus->frames(), test_array); |
| 463 ASSERT_EQ(0, |
| 464 memcmp(test_array, kTestVectorInt16, sizeof(kTestVectorInt16))); |
| 465 } |
| 466 { |
| 467 SCOPED_TRACE("SignedInt32SampleTypeTraits"); |
| 468 int32_t test_array[arraysize(kTestVectorInt32)]; |
| 469 bus->ToInterleaved<SignedInt32SampleTypeTraits>(bus->frames(), test_array); |
| 470 |
| 471 // Some compilers get better precision than others on the half-max test, so |
| 472 // let the test pass with an off by one check on the half-max. |
| 473 int32_t alternative_acceptable_result[arraysize(kTestVectorInt32)]; |
| 474 memcpy(alternative_acceptable_result, kTestVectorInt32, |
| 475 sizeof(kTestVectorInt32)); |
| 476 ASSERT_EQ(alternative_acceptable_result[4], |
| 477 std::numeric_limits<int32_t>::max() / 2); |
| 478 alternative_acceptable_result[4]++; |
| 479 |
| 480 ASSERT_TRUE( |
| 481 memcmp(test_array, kTestVectorInt32, sizeof(kTestVectorInt32)) == 0 || |
| 482 memcmp(test_array, alternative_acceptable_result, |
| 483 sizeof(alternative_acceptable_result)) == 0); |
| 484 } |
| 485 { |
| 486 SCOPED_TRACE("Float32SampleTypeTraits"); |
| 487 float test_array[arraysize(kTestVectorFloat32)]; |
| 488 bus->ToInterleaved<Float32SampleTypeTraits>(bus->frames(), test_array); |
| 489 ASSERT_EQ( |
| 490 0, memcmp(test_array, kTestVectorFloat32, sizeof(kTestVectorFloat32))); |
375 } | 491 } |
376 } | 492 } |
377 | 493 |
378 // Verify ToInterleavedPartial() interleaves audio correctly. | 494 // Verify ToInterleavedPartial() interleaves audio correctly. |
379 TEST_F(AudioBusTest, ToInterleavedPartial) { | 495 TEST_F(AudioBusTest, ToInterleavedPartial) { |
380 // Only interleave the middle two frames in each channel. | 496 // Only interleave the middle two frames in each channel. |
381 static const int kPartialStart = 1; | 497 static const int kPartialStart = 1; |
382 static const int kPartialFrames = 2; | 498 static const int kPartialFrames = 2; |
383 ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrames); | 499 ASSERT_LE(kPartialStart + kPartialFrames, kTestVectorFrameCount); |
384 | 500 |
385 std::unique_ptr<AudioBus> expected = | 501 std::unique_ptr<AudioBus> expected = |
386 AudioBus::Create(kTestVectorChannels, kTestVectorFrames); | 502 AudioBus::Create(kTestVectorChannelCount, kTestVectorFrameCount); |
387 for (int ch = 0; ch < kTestVectorChannels; ++ch) { | 503 for (int ch = 0; ch < kTestVectorChannelCount; ++ch) { |
388 memcpy(expected->channel(ch), kTestVectorResult[ch], | 504 memcpy(expected->channel(ch), kTestVectorResult[ch], |
389 kTestVectorFrames * sizeof(*expected->channel(ch))); | 505 kTestVectorFrameCount * sizeof(*expected->channel(ch))); |
390 } | 506 } |
391 | 507 |
392 int16_t test_array[arraysize(kTestVectorInt16)]; | 508 // Test deprecated version that takes |bytes_per_sample| as an input. |
393 expected->ToInterleavedPartial( | 509 { |
394 kPartialStart, kPartialFrames, sizeof(*kTestVectorInt16), test_array); | 510 SCOPED_TRACE("int16_t"); |
395 ASSERT_EQ(memcmp( | 511 int16_t test_array[arraysize(kTestVectorInt16)]; |
396 test_array, kTestVectorInt16 + kPartialStart * kTestVectorChannels, | 512 expected->ToInterleavedPartial(kPartialStart, kPartialFrames, |
397 kPartialFrames * sizeof(*kTestVectorInt16) * kTestVectorChannels), 0); | 513 sizeof(*kTestVectorInt16), test_array); |
| 514 ASSERT_EQ(0, memcmp(test_array, kTestVectorInt16 + |
| 515 kPartialStart * kTestVectorChannelCount, |
| 516 kPartialFrames * sizeof(*kTestVectorInt16) * |
| 517 kTestVectorChannelCount)); |
| 518 } |
| 519 |
| 520 // Test non-deprecated version that takes SampleTypeTraits as a template |
| 521 // parameter. |
| 522 { |
| 523 SCOPED_TRACE("Float32SampleTypeTraits"); |
| 524 float test_array[arraysize(kTestVectorFloat32)]; |
| 525 expected->ToInterleavedPartial<Float32SampleTypeTraits>( |
| 526 kPartialStart, kPartialFrames, test_array); |
| 527 ASSERT_EQ(0, memcmp(test_array, kTestVectorFloat32 + |
| 528 kPartialStart * kTestVectorChannelCount, |
| 529 kPartialFrames * sizeof(*kTestVectorFloat32) * |
| 530 kTestVectorChannelCount)); |
| 531 } |
| 532 } |
| 533 |
| 534 struct ZeroingOutTestData { |
| 535 static constexpr int kChannelCount = 2; |
| 536 static constexpr int kFrameCount = 10; |
| 537 static constexpr int kInterleavedFrameCount = 3; |
| 538 |
| 539 std::unique_ptr<AudioBus> bus_under_test; |
| 540 std::vector<float> interleaved_dummy_frames; |
| 541 |
| 542 ZeroingOutTestData() { |
| 543 // Create a bus and fill each channel with a test pattern of form |
| 544 // [1.0, 2.0, 3.0, ...] |
| 545 bus_under_test = AudioBus::Create(kChannelCount, kFrameCount); |
| 546 for (int ch = 0; ch < kChannelCount; ++ch) { |
| 547 auto sample_array_for_current_channel = bus_under_test->channel(ch); |
| 548 for (int frame_index = 0; frame_index < kFrameCount; frame_index++) { |
| 549 sample_array_for_current_channel[frame_index] = |
| 550 static_cast<float>(frame_index + 1); |
| 551 } |
| 552 } |
| 553 |
| 554 // Create a vector containing dummy interleaved samples. |
| 555 static const float kDummySampleValue = 0.123f; |
| 556 interleaved_dummy_frames.resize(kChannelCount * kInterleavedFrameCount); |
| 557 std::fill(interleaved_dummy_frames.begin(), interleaved_dummy_frames.end(), |
| 558 kDummySampleValue); |
| 559 } |
| 560 }; |
| 561 |
| 562 TEST_F(AudioBusTest, FromInterleavedZerosOutUntouchedFrames) { |
| 563 ZeroingOutTestData test_data; |
| 564 |
| 565 // Exercise |
| 566 test_data.bus_under_test->FromInterleaved<Float32SampleTypeTraits>( |
| 567 &test_data.interleaved_dummy_frames[0], test_data.kInterleavedFrameCount); |
| 568 |
| 569 // Verification |
| 570 for (int ch = 0; ch < test_data.kChannelCount; ++ch) { |
| 571 auto sample_array_for_current_channel = |
| 572 test_data.bus_under_test->channel(ch); |
| 573 for (int frame_index = test_data.kInterleavedFrameCount; |
| 574 frame_index < test_data.kFrameCount; frame_index++) { |
| 575 ASSERT_EQ(0.0f, sample_array_for_current_channel[frame_index]); |
| 576 } |
| 577 } |
| 578 } |
| 579 |
| 580 TEST_F(AudioBusTest, FromInterleavedPartialDoesNotZeroOutUntouchedFrames) { |
| 581 { |
| 582 SCOPED_TRACE("Zero write offset"); |
| 583 |
| 584 ZeroingOutTestData test_data; |
| 585 static const int kWriteOffsetInFrames = 0; |
| 586 |
| 587 // Exercise |
| 588 test_data.bus_under_test->FromInterleavedPartial<Float32SampleTypeTraits>( |
| 589 &test_data.interleaved_dummy_frames[0], kWriteOffsetInFrames, |
| 590 test_data.kInterleavedFrameCount); |
| 591 |
| 592 // Verification |
| 593 for (int ch = 0; ch < test_data.kChannelCount; ++ch) { |
| 594 auto sample_array_for_current_channel = |
| 595 test_data.bus_under_test->channel(ch); |
| 596 for (int frame_index = |
| 597 test_data.kInterleavedFrameCount + kWriteOffsetInFrames; |
| 598 frame_index < test_data.kFrameCount; frame_index++) { |
| 599 ASSERT_EQ(frame_index + 1, |
| 600 sample_array_for_current_channel[frame_index]); |
| 601 } |
| 602 } |
| 603 } |
| 604 { |
| 605 SCOPED_TRACE("Positive write offset"); |
| 606 |
| 607 ZeroingOutTestData test_data; |
| 608 static const int kWriteOffsetInFrames = 2; |
| 609 |
| 610 // Exercise |
| 611 test_data.bus_under_test->FromInterleavedPartial<Float32SampleTypeTraits>( |
| 612 &test_data.interleaved_dummy_frames[0], kWriteOffsetInFrames, |
| 613 test_data.kInterleavedFrameCount); |
| 614 |
| 615 // Verification |
| 616 for (int ch = 0; ch < test_data.kChannelCount; ++ch) { |
| 617 auto sample_array_for_current_channel = |
| 618 test_data.bus_under_test->channel(ch); |
| 619 // Check untouched frames before write offset |
| 620 for (int frame_index = 0; frame_index < kWriteOffsetInFrames; |
| 621 frame_index++) { |
| 622 ASSERT_EQ(frame_index + 1, |
| 623 sample_array_for_current_channel[frame_index]); |
| 624 } |
| 625 // Check untouched frames after write |
| 626 for (int frame_index = |
| 627 test_data.kInterleavedFrameCount + kWriteOffsetInFrames; |
| 628 frame_index < test_data.kFrameCount; frame_index++) { |
| 629 ASSERT_EQ(frame_index + 1, |
| 630 sample_array_for_current_channel[frame_index]); |
| 631 } |
| 632 } |
| 633 } |
398 } | 634 } |
399 | 635 |
400 TEST_F(AudioBusTest, Scale) { | 636 TEST_F(AudioBusTest, Scale) { |
401 std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); | 637 std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); |
402 | 638 |
403 // Fill the bus with dummy data. | 639 // Fill the bus with dummy data. |
404 static const float kFillValue = 1; | 640 static const float kFillValue = 1; |
405 for (int i = 0; i < bus->channels(); ++i) | 641 for (int i = 0; i < bus->channels(); ++i) |
406 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), kFillValue); | 642 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), kFillValue); |
407 | 643 |
408 // Adjust by an invalid volume and ensure volume is unchanged. | 644 // Adjust by an invalid volume and ensure volume is unchanged. |
409 bus->Scale(-1); | 645 bus->Scale(-1); |
410 for (int i = 0; i < bus->channels(); ++i) { | 646 for (int i = 0; i < bus->channels(); ++i) { |
411 SCOPED_TRACE("Invalid Scale"); | 647 SCOPED_TRACE("Invalid Scale"); |
412 VerifyValue(bus->channel(i), bus->frames(), kFillValue); | 648 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), kFillValue); |
413 } | 649 } |
414 | 650 |
415 // Verify correct volume adjustment. | 651 // Verify correct volume adjustment. |
416 static const float kVolume = 0.5; | 652 static const float kVolume = 0.5; |
417 bus->Scale(kVolume); | 653 bus->Scale(kVolume); |
418 for (int i = 0; i < bus->channels(); ++i) { | 654 for (int i = 0; i < bus->channels(); ++i) { |
419 SCOPED_TRACE("Half Scale"); | 655 SCOPED_TRACE("Half Scale"); |
420 VerifyValue(bus->channel(i), bus->frames(), kFillValue * kVolume); | 656 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), |
| 657 kFillValue * kVolume); |
421 } | 658 } |
422 | 659 |
423 // Verify zero volume case. | 660 // Verify zero volume case. |
424 bus->Scale(0); | 661 bus->Scale(0); |
425 for (int i = 0; i < bus->channels(); ++i) { | 662 for (int i = 0; i < bus->channels(); ++i) { |
426 SCOPED_TRACE("Zero Scale"); | 663 SCOPED_TRACE("Zero Scale"); |
427 VerifyValue(bus->channel(i), bus->frames(), 0); | 664 VerifyArrayIsFilledWithValue(bus->channel(i), bus->frames(), 0); |
428 } | 665 } |
429 } | 666 } |
430 | 667 |
431 } // namespace media | 668 } // namespace media |
OLD | NEW |