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

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: Lint. 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
« media/base/audio_bus.cc ('K') | « media/base/audio_bus.cc ('k') | no next file » | 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 <limits>
6
7 #include "base/stringprintf.h"
5 #include "media/audio/audio_parameters.h" 8 #include "media/audio/audio_parameters.h"
6 #include "media/base/audio_bus.h" 9 #include "media/base/audio_bus.h"
7 #include "media/base/channel_layout.h" 10 #include "media/base/channel_layout.h"
8 #include "testing/gtest/include/gtest/gtest.h" 11 #include "testing/gtest/include/gtest/gtest.h"
9 12
10 static const int kChannels = 6; 13 static const int kChannels = 6;
11 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_5_1; 14 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_5_1;
12 // Use a buffer size which is intentionally not a multiple of 16; see 15 // Use a buffer size which is intentionally not a multiple of 16; see
13 // kChannelAlignment in audio_bus.cc. 16 // kChannelAlignment in audio_bus.cc.
14 static const int kFrameCount = 1234; 17 static const int kFrameCount = 1234;
18 static const int kSampleRate = 48000;
15 19
16 namespace media { 20 namespace media {
17 21
18 class AudioBusTest : public testing::Test { 22 class AudioBusTest : public testing::Test {
19 public: 23 public:
20 AudioBusTest() {} 24 AudioBusTest() {}
21 ~AudioBusTest() { 25 ~AudioBusTest() {
22 for (size_t i = 0; i < data_.size(); ++i) 26 for (size_t i = 0; i < data_.size(); ++i)
23 base::AlignedFree(data_[i]); 27 base::AlignedFree(data_[i]);
24 } 28 }
25 29
26 // Validate parameters returned by AudioBus v.s. the constructed parameters. 30 // Validate parameters returned by AudioBus v.s. the constructed parameters.
27 void VerifyParams(AudioBus* bus) { 31 void VerifyParams(AudioBus* bus) {
28 EXPECT_EQ(kChannels, bus->channels()); 32 EXPECT_EQ(kChannels, bus->channels());
29 EXPECT_EQ(kFrameCount, bus->frames()); 33 EXPECT_EQ(kFrameCount, bus->frames());
30 } 34 }
31 35
32 void VerifyValue(const float data[], int size, float value) { 36 void VerifyValue(const float data[], int size, float value) {
33 for (int i = 0; i < size; ++i) 37 for (int i = 0; i < size; ++i)
34 ASSERT_FLOAT_EQ(value, data[i]); 38 ASSERT_FLOAT_EQ(value, data[i]);
35 } 39 }
36 40
41 // Verify values for each channel in |result| against |expected|.
42 void VerifyBus(const AudioBus* result, const AudioBus* expected) {
43 ASSERT_EQ(expected->channels(), result->channels());
44 ASSERT_EQ(expected->frames(), result->frames());
45 for (int ch = 0; ch < result->channels(); ++ch) {
46 for (int i = 0; i < result->frames(); ++i) {
47 SCOPED_TRACE(base::StringPrintf("ch=%d, i=%d", ch, i));
henrika (OOO until Aug 14) 2012/08/15 09:59:37 Cool. I have never seen this before. Thanks.
48 ASSERT_FLOAT_EQ(expected->channel(ch)[i], result->channel(ch)[i]);
49 }
50 }
51 }
52
37 // Read and write to the full extent of the allocated channel data. Also test 53 // 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 54 // 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). 55 // is 16-byte aligned as advertised (see kChannelAlignment in audio_bus.cc).
40 void VerifyChannelData(AudioBus* bus) { 56 void VerifyChannelData(AudioBus* bus) {
41 for (int i = 0; i < bus->channels(); ++i) { 57 for (int i = 0; i < bus->channels(); ++i) {
42 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(bus->channel(i)) & 0x0F); 58 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(bus->channel(i)) & 0x0F);
43 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i); 59 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i);
44 } 60 }
45 61
46 for (int i = 0; i < bus->channels(); ++i) 62 for (int i = 0; i < bus->channels(); ++i)
47 VerifyValue(bus->channel(i), bus->frames(), i); 63 VerifyValue(bus->channel(i), bus->frames(), i);
48 64
49 bus->Zero(); 65 bus->Zero();
50 for (int i = 0; i < bus->channels(); ++i) 66 for (int i = 0; i < bus->channels(); ++i)
51 VerifyValue(bus->channel(i), bus->frames(), 0); 67 VerifyValue(bus->channel(i), bus->frames(), 0);
52 } 68 }
53 69
54
55 protected: 70 protected:
56 std::vector<float*> data_; 71 std::vector<float*> data_;
57 72
58 DISALLOW_COPY_AND_ASSIGN(AudioBusTest); 73 DISALLOW_COPY_AND_ASSIGN(AudioBusTest);
59 }; 74 };
60 75
61 // Verify basic Create(...) method works as advertised. 76 // Verify basic Create(...) method works as advertised.
62 TEST_F(AudioBusTest, Create) { 77 TEST_F(AudioBusTest, Create) {
63 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); 78 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount);
64 VerifyParams(bus.get()); 79 VerifyParams(bus.get());
65 VerifyChannelData(bus.get()); 80 VerifyChannelData(bus.get());
66 } 81 }
67 82
68 // Verify Create(...) using AudioParameters works as advertised. 83 // Verify Create(...) using AudioParameters works as advertised.
69 TEST_F(AudioBusTest, CreateUsingAudioParameters) { 84 TEST_F(AudioBusTest, CreateUsingAudioParameters) {
70 scoped_ptr<AudioBus> bus = AudioBus::Create(AudioParameters( 85 scoped_ptr<AudioBus> bus = AudioBus::Create(AudioParameters(
71 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, 48000, 32, 86 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32,
72 kFrameCount)); 87 kFrameCount));
73 VerifyParams(bus.get()); 88 VerifyParams(bus.get());
74 VerifyChannelData(bus.get()); 89 VerifyChannelData(bus.get());
90 EXPECT_EQ(bus->sample_rate(), kSampleRate);
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.
henrika (OOO until Aug 14) 2012/08/15 09:59:37 Strange sentence. Please read it again ;-)
DaleCurtis 2012/08/16 01:54:14 Not sure what's strange about it? :)
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::ExpectedDataSize(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 EXPECT_EQ(bus->sample_rate(), kSampleRate);
138
139 // Try with an unaligned pointer.
140 bus = AudioBus::WrapBlock(params, data.get());
141 VerifyParams(bus.get());
142 VerifyChannelData(bus.get());
143 EXPECT_EQ(bus->sample_rate(), kSampleRate);
144 }
145
90 // Simulate a shared memory transfer and verify results. 146 // Simulate a shared memory transfer and verify results.
91 TEST_F(AudioBusTest, AudioData) { 147 TEST_F(AudioBusTest, AudioData) {
148 // Create one bus with AudioParameters and the other through direct values to
149 // test for parity between the functions.
150 AudioParameters params(
151 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32,
152 kFrameCount);
92 scoped_ptr<AudioBus> bus1 = AudioBus::Create(kChannels, kFrameCount); 153 scoped_ptr<AudioBus> bus1 = AudioBus::Create(kChannels, kFrameCount);
93 scoped_ptr<AudioBus> bus2 = AudioBus::Create(kChannels, kFrameCount); 154 scoped_ptr<AudioBus> bus2 = AudioBus::Create(params);
155 // Flip the order of which bus checks using params vs created with for parity.
156 ASSERT_EQ(bus1->data_size(), AudioBus::ExpectedDataSize(params));
157 ASSERT_EQ(bus2->data_size(),
158 AudioBus::ExpectedDataSize(kChannels, kFrameCount));
94 159
95 // Fill |bus1| with dummy data and zero out |bus2|. 160 // Fill |bus1| with dummy data and zero out |bus2|.
96 for (int i = 0; i < bus1->channels(); ++i) 161 for (int i = 0; i < bus1->channels(); ++i)
97 std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i); 162 std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i);
98 bus2->Zero(); 163 bus2->Zero();
99 164
100 // Transfer audio data from |bus1| to |bus2|. 165 // Transfer audio data from |bus1| to |bus2|.
101 ASSERT_EQ(bus1->data_size(), bus2->data_size()); 166 ASSERT_EQ(bus1->data_size(), bus2->data_size());
102 memcpy(bus2->data(), bus1->data(), bus1->data_size()); 167 memcpy(bus2->data(), bus1->data(), bus1->data_size());
103 168
104 for (int i = 0; i < bus2->channels(); ++i) 169 for (int i = 0; i < bus2->channels(); ++i)
105 VerifyValue(bus2->channel(i), bus2->frames(), i); 170 VerifyValue(bus2->channel(i), bus2->frames(), i);
106 } 171 }
107 172
173 // Simulate a shared memory transfer from a wrapped to unwrapped AudioBus.
174 TEST_F(AudioBusTest, AudioDataWrapped) {
175 // Create one bus with AudioParameters and the other through direct values to
176 // test for parity between the functions.
177 AudioParameters params(
178 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, 32,
179 kFrameCount);
180 scoped_ptr<AudioBus> bus1 = AudioBus::Create(kChannels, kFrameCount);
181 ASSERT_EQ(bus1->data_size(), AudioBus::ExpectedDataSize(params));
182 scoped_ptr<AudioBus> bus2 = AudioBus::WrapBlock(params, bus1->data());
183
184 // Fill |bus1| with dummy data.
185 for (int i = 0; i < bus1->channels(); ++i)
186 std::fill(bus1->channel(i), bus1->channel(i) + bus1->frames(), i);
187
188 // Verify the data is correct inside of |bus2|.
189 for (int i = 0; i < bus2->channels(); ++i)
190 VerifyValue(bus2->channel(i), bus2->frames(), i);
191
192 // Zero |bus2| and ensure |bus1| is zero'd
193 bus2->Zero();
194 for (int i = 0; i < bus1->channels(); ++i)
195 VerifyValue(bus1->channel(i), bus1->frames(), 0);
196
197 // Fill |bus2| with dummy data.
198 for (int i = 0; i < bus2->channels(); ++i)
199 std::fill(bus2->channel(i), bus2->channel(i) + bus2->frames(), i);
200
201 // Verify the data is correct inside of |bus1|.
202 for (int i = 0; i < bus1->channels(); ++i)
203 VerifyValue(bus1->channel(i), bus1->frames(), i);
204 }
205
108 // Verify Zero() and ZeroFrames(...) utility methods work as advertised. 206 // Verify Zero() and ZeroFrames(...) utility methods work as advertised.
109 TEST_F(AudioBusTest, Zero) { 207 TEST_F(AudioBusTest, Zero) {
110 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount); 208 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kFrameCount);
111 209
112 // First fill the bus with dummy data. 210 // First fill the bus with dummy data.
113 for (int i = 0; i < bus->channels(); ++i) 211 for (int i = 0; i < bus->channels(); ++i)
114 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1); 212 std::fill(bus->channel(i), bus->channel(i) + bus->frames(), i + 1);
115 213
116 // Zero half the frames of each channel. 214 // Zero half the frames of each channel.
117 bus->ZeroFrames(kFrameCount / 2); 215 bus->ZeroFrames(kFrameCount / 2);
118 for (int i = 0; i < bus->channels(); ++i) 216 for (int i = 0; i < bus->channels(); ++i)
119 VerifyValue(bus->channel(i), kFrameCount / 2, 0); 217 VerifyValue(bus->channel(i), kFrameCount / 2, 0);
120 218
121 // Zero all the frames of each channel. 219 // Zero all the frames of each channel.
122 bus->Zero(); 220 bus->Zero();
123 for (int i = 0; i < bus->channels(); ++i) 221 for (int i = 0; i < bus->channels(); ++i)
124 VerifyValue(bus->channel(i), bus->frames(), 0); 222 VerifyValue(bus->channel(i), bus->frames(), 0);
125 } 223 }
126 224
225 // Each test vector represents two channels of data in the following arbitrary
226 // layout: <min, zero, max, min, zero, max, zero, zero>.
227 static const int kTestVectorSize = 8;
228 static const uint8 kTestVectorUint8[kTestVectorSize] = {
229 0, -kint8min, kuint8max, 0, -kint8min, kuint8max, -kint8min, -kint8min };
230 static const int16 kTestVectorInt16[kTestVectorSize] = {
231 kint16min, 0, kint16max, kint16min, 0, kint16max, 0, 0 };
232 static const int32 kTestVectorInt32[kTestVectorSize] = {
233 kint32min, 0, kint32max, kint32min, 0, kint32max, 0, 0 };
234
235 // Expected results, the last value is unused.
236 static const int kTestVectorFrames = kTestVectorSize / 2;
237 static const float kTestVectorResult[][kTestVectorFrames] = {
238 { -1, 1, 0, 0 }, { 0, -1, 1, 0 }};
239 static const int kTestVectorChannels = arraysize(kTestVectorResult);
240
241 TEST_F(AudioBusTest, FromInterleaved) {
242 scoped_ptr<AudioBus> bus = AudioBus::Create(
243 kTestVectorChannels, kTestVectorFrames);
244 scoped_ptr<AudioBus> expected = AudioBus::Create(
245 kTestVectorChannels, kTestVectorFrames);
246 for (int ch = 0; ch < kTestVectorChannels; ++ch) {
247 memcpy(expected->channel(ch), kTestVectorResult[ch],
248 kTestVectorFrames * sizeof(*expected->channel(ch)));
249 }
250 {
251 SCOPED_TRACE("uint8");
252 bus->FromInterleaved(
253 kTestVectorUint8, kTestVectorFrames, sizeof(*kTestVectorUint8));
254 VerifyBus(bus.get(), expected.get());
255 }
256 {
257 SCOPED_TRACE("int16");
258 bus->FromInterleaved(
259 kTestVectorInt16, kTestVectorFrames, sizeof(*kTestVectorInt16));
260 VerifyBus(bus.get(), expected.get());
261 }
262 {
263 SCOPED_TRACE("int32");
264 bus->FromInterleaved(
265 kTestVectorInt32, kTestVectorFrames, sizeof(*kTestVectorInt32));
266 VerifyBus(bus.get(), expected.get());
267 }
268 }
269
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(test_array, bus->frames(), sizeof(*kTestVectorUint8));
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(test_array, bus->frames(), sizeof(*kTestVectorInt16));
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(test_array, bus->frames(), sizeof(*kTestVectorInt32));
296 ASSERT_EQ(memcmp(
297 test_array, kTestVectorInt32, arraysize(kTestVectorInt32)), 0);
298 }
299 }
300
127 } // namespace media 301 } // namespace media
OLDNEW
« media/base/audio_bus.cc ('K') | « media/base/audio_bus.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698