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

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

Issue 10824304: Upgrade AudioBus to support wrapping, interleaving. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments. Created 8 years, 4 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 | Annotate | Revision Log
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 <limits>
6
7 #include "base/stringprintf.h"
8 #include "base/time.h"
5 #include "media/audio/audio_parameters.h" 9 #include "media/audio/audio_parameters.h"
6 #include "media/base/audio_bus.h" 10 #include "media/base/audio_bus.h"
7 #include "media/base/channel_layout.h" 11 #include "media/base/channel_layout.h"
8 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
9 13
10 static const int kChannels = 6; 14 static const int kChannels = 6;
11 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_5_1; 15 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_5_1;
12 // Use a buffer size which is intentionally not a multiple of 16; see 16 // Use a buffer size which is intentionally not a multiple of 16; see
13 // kChannelAlignment in audio_bus.cc. 17 // kChannelAlignment in audio_bus.cc.
14 static const int kFrameCount = 1234; 18 static const int kFrameCount = 1234;
19 static const int kSampleRate = 48000;
15 20
16 namespace media { 21 namespace media {
17 22
18 class AudioBusTest : public testing::Test { 23 class AudioBusTest : public testing::Test {
19 public: 24 public:
20 AudioBusTest() {} 25 AudioBusTest() {}
21 ~AudioBusTest() { 26 ~AudioBusTest() {
22 for (size_t i = 0; i < data_.size(); ++i) 27 for (size_t i = 0; i < data_.size(); ++i)
23 base::AlignedFree(data_[i]); 28 base::AlignedFree(data_[i]);
24 } 29 }
25 30
26 // Validate parameters returned by AudioBus v.s. the constructed parameters. 31 // Validate parameters returned by AudioBus v.s. the constructed parameters.
27 void VerifyParams(AudioBus* bus) { 32 void VerifyParams(AudioBus* bus) {
28 EXPECT_EQ(kChannels, bus->channels()); 33 EXPECT_EQ(kChannels, bus->channels());
29 EXPECT_EQ(kFrameCount, bus->frames()); 34 EXPECT_EQ(kFrameCount, bus->frames());
30 } 35 }
31 36
32 void VerifyValue(const float data[], int size, float value) { 37 void VerifyValue(const float data[], int size, float value) {
33 for (int i = 0; i < size; ++i) 38 for (int i = 0; i < size; ++i)
34 ASSERT_FLOAT_EQ(value, data[i]); 39 ASSERT_FLOAT_EQ(value, data[i]);
35 } 40 }
36 41
42 // Verify values for each channel in |result| against |expected|.
43 void VerifyBus(const AudioBus* result, const AudioBus* expected) {
44 ASSERT_EQ(expected->channels(), result->channels());
45 ASSERT_EQ(expected->frames(), result->frames());
46 for (int ch = 0; ch < result->channels(); ++ch) {
47 for (int i = 0; i < result->frames(); ++i) {
48 SCOPED_TRACE(base::StringPrintf("ch=%d, i=%d", ch, i));
49 ASSERT_FLOAT_EQ(expected->channel(ch)[i], result->channel(ch)[i]);
50 }
51 }
52 }
53
37 // Read and write to the full extent of the allocated channel data. Also test 54 // Read and write to the full extent of the allocated channel data. Also test
38 // the Zero() method and verify it does as advertised. Also test data if data 55 // the Zero() method and verify it does as advertised. Also test data if data
39 // is 16-byte aligned as advertised (see kChannelAlignment in audio_bus.cc). 56 // is 16-byte aligned as advertised (see kChannelAlignment in audio_bus.cc).
40 void VerifyChannelData(AudioBus* bus) { 57 void VerifyChannelData(AudioBus* bus) {
41 for (int i = 0; i < bus->channels(); ++i) { 58 for (int i = 0; i < bus->channels(); ++i) {
42 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(bus->channel(i)) & 0x0F); 59 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(bus->channel(i)) & 0x0F);
43 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i); 60 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i);
44 } 61 }
45 62
46 for (int i = 0; i < bus->channels(); ++i) 63 for (int i = 0; i < bus->channels(); ++i)
47 VerifyValue(bus->channel(i), bus->frames(), i); 64 VerifyValue(bus->channel(i), bus->frames(), i);
48 65
49 bus->Zero(); 66 bus->Zero();
50 for (int i = 0; i < bus->channels(); ++i) 67 for (int i = 0; i < bus->channels(); ++i)
51 VerifyValue(bus->channel(i), bus->frames(), 0); 68 VerifyValue(bus->channel(i), bus->frames(), 0);
52 } 69 }
53 70
54
55 protected: 71 protected:
56 std::vector<float*> data_; 72 std::vector<float*> data_;
57 73
58 DISALLOW_COPY_AND_ASSIGN(AudioBusTest); 74 DISALLOW_COPY_AND_ASSIGN(AudioBusTest);
59 }; 75 };
60 76
61 // Verify basic Create(...) method works as advertised. 77 // Verify basic Create(...) method works as advertised.
62 TEST_F(AudioBusTest, Create) { 78 TEST_F(AudioBusTest, Create) {
63 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); 79 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount);
64 VerifyParams(bus.get()); 80 VerifyParams(bus.get());
65 VerifyChannelData(bus.get()); 81 VerifyChannelData(bus.get());
66 } 82 }
67 83
68 // Verify Create(...) using AudioParameters works as advertised. 84 // Verify Create(...) using AudioParameters works as advertised.
69 TEST_F(AudioBusTest, CreateUsingAudioParameters) { 85 TEST_F(AudioBusTest, CreateUsingAudioParameters) {
70 scoped_ptr<AudioBus> bus = AudioBus::Create(AudioParameters( 86 scoped_ptr<AudioBus> bus = AudioBus::Create(AudioParameters(
71 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, 48000, 32, 87 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32,
72 kFrameCount)); 88 kFrameCount));
73 VerifyParams(bus.get()); 89 VerifyParams(bus.get());
74 VerifyChannelData(bus.get()); 90 VerifyChannelData(bus.get());
75 } 91 }
76 92
77 // Verify an AudioBus created via wrapping works as advertised. 93 // Verify an AudioBus created via wrapping a vector works as advertised.
78 TEST_F(AudioBusTest, Wrap) { 94 TEST_F(AudioBusTest, WrapVector) {
79 data_.reserve(kChannels); 95 data_.reserve(kChannels);
80 for (int i = 0; i < kChannels; ++i) { 96 for (int i = 0; i < kChannels; ++i) {
81 data_.push_back(static_cast<float*>(base::AlignedAlloc( 97 data_.push_back(static_cast<float*>(base::AlignedAlloc(
82 sizeof(*data_[i]) * kFrameCount, 16))); 98 sizeof(*data_[i]) * kFrameCount, 16)));
83 } 99 }
84 100
85 scoped_ptr<AudioBus> bus = AudioBus::WrapVector(kFrameCount, data_); 101 scoped_ptr<AudioBus> bus = AudioBus::WrapVector(kFrameCount, data_);
86 VerifyParams(bus.get()); 102 VerifyParams(bus.get());
87 VerifyChannelData(bus.get()); 103 VerifyChannelData(bus.get());
88 } 104 }
89 105
106 // Verify an AudioBus created via wrapping a memory block works as advertised.
107 TEST_F(AudioBusTest, WrapBlock) {
108 // Choose a data size that allows us to slide |data| to be 16-byte unaligned.
109 int data_size = AudioBus::BlockSize(kChannels, kFrameCount) + 16;
110 scoped_ptr<uint8> data(new uint8[data_size]);
111
112 // Slide our pointer until it's unaligned.
113 uint8* data_unaligned = data.get();
114 while ((reinterpret_cast<uintptr_t>(data_unaligned) & 0x0F) == 0U)
115 data_unaligned++;
116
117 // Try with an aligned pointer.
118 scoped_ptr<AudioBus> bus = AudioBus::WrapBlock(
119 kChannels, kFrameCount, data.get());
120 VerifyParams(bus.get());
121 VerifyChannelData(bus.get());
122
123 // Try with an unaligned pointer.
124 bus = AudioBus::WrapBlock(kChannels, kFrameCount, data_unaligned);
125 VerifyParams(bus.get());
126 VerifyChannelData(bus.get());
127
128 // Repeat using AudioParameters.
129 AudioParameters params(
130 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32,
131 kFrameCount);
132
133 // Try with an aligned pointer.
134 bus = AudioBus::WrapBlock(params, data.get());
135 VerifyParams(bus.get());
136 VerifyChannelData(bus.get());
137
138 // Try with an unaligned pointer.
139 bus = AudioBus::WrapBlock(params, data.get());
140 VerifyParams(bus.get());
141 VerifyChannelData(bus.get());
142 }
143
90 // Simulate a shared memory transfer and verify results. 144 // Simulate a shared memory transfer and verify results.
91 TEST_F(AudioBusTest, AudioData) { 145 TEST_F(AudioBusTest, AudioData) {
146 // Create one bus with AudioParameters and the other through direct values to
147 // test for parity between the functions.
148 AudioParameters params(
149 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32,
150 kFrameCount);
92 scoped_ptr<AudioBus> bus1 = AudioBus::Create(kChannels, kFrameCount); 151 scoped_ptr<AudioBus> bus1 = AudioBus::Create(kChannels, kFrameCount);
93 scoped_ptr<AudioBus> bus2 = AudioBus::Create(kChannels, kFrameCount); 152 scoped_ptr<AudioBus> bus2 = AudioBus::Create(params);
153 // Flip the order of which bus checks using params vs created with for parity.
154 ASSERT_EQ(bus1->data_size(), AudioBus::BlockSize(params));
155 ASSERT_EQ(bus2->data_size(),
156 AudioBus::BlockSize(kChannels, kFrameCount));
94 157
95 // Fill |bus1| with dummy data and zero out |bus2|. 158 // Fill |bus1| with dummy data and zero out |bus2|.
96 for (int i = 0; i < bus1->channels(); ++i) 159 for (int i = 0; i < bus1->channels(); ++i)
97 std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i); 160 std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i);
98 bus2->Zero(); 161 bus2->Zero();
99 162
100 // Transfer audio data from |bus1| to |bus2|. 163 // Transfer audio data from |bus1| to |bus2|.
101 ASSERT_EQ(bus1->data_size(), bus2->data_size()); 164 ASSERT_EQ(bus1->data_size(), bus2->data_size());
102 memcpy(bus2->data(), bus1->data(), bus1->data_size()); 165 memcpy(bus2->data(), bus1->data(), bus1->data_size());
103 166
104 for (int i = 0; i < bus2->channels(); ++i) 167 for (int i = 0; i < bus2->channels(); ++i)
105 VerifyValue(bus2->channel(i), bus2->frames(), i); 168 VerifyValue(bus2->channel(i), bus2->frames(), i);
106 } 169 }
107 170
171 // Simulate a shared memory transfer from a wrapped to unwrapped AudioBus.
172 TEST_F(AudioBusTest, AudioDataWrapped) {
173 // Create one bus with AudioParameters and the other through direct values to
174 // test for parity between the functions.
175 AudioParameters params(
176 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32,
177 kFrameCount);
178 scoped_ptr<AudioBus> bus1 = AudioBus::Create(kChannels, kFrameCount);
179 ASSERT_EQ(bus1->data_size(), AudioBus::BlockSize(params));
180 scoped_ptr<AudioBus> bus2 = AudioBus::WrapBlock(params, bus1->data());
181
182 // Fill |bus1| with dummy data.
183 for (int i = 0; i < bus1->channels(); ++i)
184 std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i);
185
186 // Verify the data is correct inside of |bus2|.
187 for (int i = 0; i < bus2->channels(); ++i)
188 VerifyValue(bus2->channel(i), bus2->frames(), i);
189
190 // Zero |bus2| and ensure |bus1| is zero'd
191 bus2->Zero();
192 for (int i = 0; i < bus1->channels(); ++i)
193 VerifyValue(bus1->channel(i), bus1->frames(), 0);
194
195 // Fill |bus2| with dummy data.
196 for (int i = 0; i < bus2->channels(); ++i)
197 std::fill(bus2->channel(i), bus2->channel(i) + bus2->frames(), i);
198
199 // Verify the data is correct inside of |bus1|.
200 for (int i = 0; i < bus1->channels(); ++i)
201 VerifyValue(bus1->channel(i), bus1->frames(), i);
202 }
203
108 // Verify Zero() and ZeroFrames(...) utility methods work as advertised. 204 // Verify Zero() and ZeroFrames(...) utility methods work as advertised.
109 TEST_F(AudioBusTest, Zero) { 205 TEST_F(AudioBusTest, Zero) {
110 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); 206 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount);
111 207
112 // First fill the bus with dummy data. 208 // First fill the bus with dummy data.
113 for (int i = 0; i < bus->channels(); ++i) 209 for (int i = 0; i < bus->channels(); ++i)
114 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); 210 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1);
115 211
116 // Zero half the frames of each channel. 212 // Zero half the frames of each channel.
117 bus->ZeroFrames(kFrameCount / 2); 213 bus->ZeroFrames(kFrameCount / 2);
118 for (int i = 0; i < bus->channels(); ++i) 214 for (int i = 0; i < bus->channels(); ++i)
119 VerifyValue(bus->channel(i), kFrameCount / 2, 0); 215 VerifyValue(bus->channel(i), kFrameCount / 2, 0);
120 216
121 // Zero all the frames of each channel. 217 // Zero all the frames of each channel.
122 bus->Zero(); 218 bus->Zero();
123 for (int i = 0; i < bus->channels(); ++i) 219 for (int i = 0; i < bus->channels(); ++i)
124 VerifyValue(bus->channel(i), bus->frames(), 0); 220 VerifyValue(bus->channel(i), bus->frames(), 0);
125 } 221 }
126 222
223 // Each test vector represents two channels of data in the following arbitrary
224 // layout: <min, zero, max, min, zero, max, zero, zero>.
225 static const int kTestVectorSize = 8;
226 static const uint8 kTestVectorUint8[kTestVectorSize] = {
227 0, -kint8min, kuint8max, 0, -kint8min, kuint8max, -kint8min, -kint8min };
228 static const int16 kTestVectorInt16[kTestVectorSize] = {
229 kint16min, 0, kint16max, kint16min, 0, kint16max, 0, 0 };
230 static const int32 kTestVectorInt32[kTestVectorSize] = {
231 kint32min, 0, kint32max, kint32min, 0, kint32max, 0, 0 };
232
233 // Expected results.
234 static const int kTestVectorFrames = kTestVectorSize / 2;
235 static const float kTestVectorResult[][kTestVectorFrames] = {
236 { -1, 1, 0, 0 }, { 0, -1, 1, 0 }};
237 static const int kTestVectorChannels = arraysize(kTestVectorResult);
238
239 // Verify FromInterleaved() deinterleaves audio in suported formats correctly.
240 TEST_F(AudioBusTest, FromInterleaved) {
241 scoped_ptr<AudioBus> bus = AudioBus::Create(
242 kTestVectorChannels, kTestVectorFrames);
243 scoped_ptr<AudioBus> expected = AudioBus::Create(
244 kTestVectorChannels, kTestVectorFrames);
245 for (int ch = 0; ch < kTestVectorChannels; ++ch) {
246 memcpy(expected->channel(ch), kTestVectorResult[ch],
247 kTestVectorFrames * sizeof(*expected->channel(ch)));
248 }
249 {
250 SCOPED_TRACE("uint8");
251 bus->FromInterleaved(
252 kTestVectorUint8, kTestVectorFrames, sizeof(*kTestVectorUint8));
253 VerifyBus(bus.get(), expected.get());
254 }
255 {
256 SCOPED_TRACE("int16");
257 bus->FromInterleaved(
258 kTestVectorInt16, kTestVectorFrames, sizeof(*kTestVectorInt16));
259 VerifyBus(bus.get(), expected.get());
260 }
261 {
262 SCOPED_TRACE("int32");
263 bus->FromInterleaved(
264 kTestVectorInt32, kTestVectorFrames, sizeof(*kTestVectorInt32));
265 VerifyBus(bus.get(), expected.get());
266 }
267 }
268
269 // Verify ToInterleaved() interleaves audio in suported formats correctly.
270 TEST_F(AudioBusTest, ToInterleaved) {
271 scoped_ptr<AudioBus> bus = AudioBus::Create(
272 kTestVectorChannels, kTestVectorFrames);
273 // Fill the bus with our test vector.
274 for (int ch = 0; ch < kTestVectorChannels; ++ch) {
275 memcpy(bus->channel(ch), kTestVectorResult[ch],
276 kTestVectorFrames * sizeof(*bus->channel(ch)));
277 }
278 {
279 SCOPED_TRACE("uint8");
280 uint8 test_array[arraysize(kTestVectorUint8)];
281 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorUint8), test_array);
282 ASSERT_EQ(memcmp(
283 test_array, kTestVectorUint8, arraysize(kTestVectorUint8)), 0);
284 }
285 {
286 SCOPED_TRACE("int16");
287 int16 test_array[arraysize(kTestVectorInt16)];
288 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt16), test_array);
289 ASSERT_EQ(memcmp(
290 test_array, kTestVectorInt16, arraysize(kTestVectorInt16)), 0);
291 }
292 {
293 SCOPED_TRACE("int32");
294 int32 test_array[arraysize(kTestVectorInt32)];
295 bus->ToInterleaved(bus->frames(), sizeof(*kTestVectorInt32), test_array);
296 ASSERT_EQ(memcmp(
297 test_array, kTestVectorInt32, arraysize(kTestVectorInt32)), 0);
298 }
299 }
300
127 } // namespace media 301 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698