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

Side by Side Diff: media/base/audio_bus_unittest.cc

Issue 2024993004: AudioBus: Add a ToInterleavedFloat() method to AudioBus (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed a todo Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/base/audio_bus.cc ('k') | media/base/audio_sample_types.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
OLDNEW
« no previous file with comments | « media/base/audio_bus.cc ('k') | media/base/audio_sample_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698