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 // The format of these tests are to enqueue a known amount of data and then | 5 // The format of these tests are to enqueue a known amount of data and then |
6 // request the exact amount we expect in order to dequeue the known amount of | 6 // request the exact amount we expect in order to dequeue the known amount of |
7 // data. This ensures that for any rate we are consuming input data at the | 7 // data. This ensures that for any rate we are consuming input data at the |
8 // correct rate. We always pass in a very large destination buffer with the | 8 // correct rate. We always pass in a very large destination buffer with the |
9 // expectation that FillBuffer() will fill as much as it can but no more. | 9 // expectation that FillBuffer() will fill as much as it can but no more. |
10 | 10 |
11 #include <algorithm> // For std::min(). | |
11 #include <cmath> | 12 #include <cmath> |
12 | 13 |
13 #include "base/bind.h" | 14 #include "base/bind.h" |
14 #include "base/callback.h" | 15 #include "base/callback.h" |
16 #include "base/memory/scoped_ptr.h" | |
15 #include "media/base/audio_buffer.h" | 17 #include "media/base/audio_buffer.h" |
16 #include "media/base/audio_bus.h" | 18 #include "media/base/audio_bus.h" |
17 #include "media/base/buffers.h" | 19 #include "media/base/buffers.h" |
18 #include "media/base/channel_layout.h" | 20 #include "media/base/channel_layout.h" |
19 #include "media/base/test_helpers.h" | 21 #include "media/base/test_helpers.h" |
20 #include "media/filters/audio_renderer_algorithm.h" | 22 #include "media/filters/audio_renderer_algorithm.h" |
23 #include "media/filters/wsola_internals.h" | |
21 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
22 | |
23 namespace media { | 25 namespace media { |
24 | 26 |
25 static const int kFrameSize = 250; | 27 static const int kFrameSize = 250; |
26 static const int kSamplesPerSecond = 3000; | 28 static const int kSamplesPerSecond = 3000; |
27 static const SampleFormat kSampleFormat = kSampleFormatS16; | 29 static const SampleFormat kSampleFormat = kSampleFormatS16; |
30 static const int kOutputDurationInSec = 10; | |
DaleCurtis
2013/08/13 21:11:04
As mentioned below, these tests are traditionally
turaj
2013/08/16 22:13:56
I run WSOLA for 4 seconds, if that results in too
| |
31 | |
32 static void FillWithSquarePulseTrain( | |
33 int half_pulse_width, int offset, int channel, AudioBus* audio_bus) { | |
34 ASSERT_GE(offset, 0); | |
35 ASSERT_LT(offset, audio_bus->frames()); | |
36 | |
37 float* ch = audio_bus->channel(channel); | |
38 | |
39 // Fill backward from |offset| - 1 toward zero, starting with -1, alternating | |
40 // between -1 and 1 every |pulse_width| samples. | |
41 float pulse = -1.0f; | |
42 for (int n = offset - 1, k = 0; n >= 0; --n, ++k) { | |
43 if (k >= half_pulse_width) { | |
44 pulse = -pulse; | |
45 k = 0; | |
46 } | |
47 ch[n] = pulse; | |
48 } | |
49 | |
50 // Fill forward from |offset| towards the end, starting with 1, alternating | |
51 // between 1 and -1 every |pulse_width| samples. | |
52 pulse = 1.0f; | |
53 for (int n = offset, k = 0; n < audio_bus->frames(); ++n, ++k) { | |
54 if (k >= half_pulse_width) { | |
55 pulse = -pulse; | |
56 k = 0; | |
57 } | |
58 ch[n] = pulse; | |
59 } | |
60 } | |
61 | |
28 | 62 |
29 class AudioRendererAlgorithmTest : public testing::Test { | 63 class AudioRendererAlgorithmTest : public testing::Test { |
30 public: | 64 public: |
31 AudioRendererAlgorithmTest() | 65 AudioRendererAlgorithmTest() |
32 : frames_enqueued_(0), | 66 : frames_enqueued_(0), |
33 channels_(0), | 67 channels_(0), |
34 sample_format_(kUnknownSampleFormat), | 68 sample_format_(kUnknownSampleFormat), |
35 bytes_per_sample_(0) { | 69 bytes_per_sample_(0) { |
36 } | 70 } |
37 | 71 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
111 int initial_frames_buffered) { | 145 int initial_frames_buffered) { |
112 int frame_delta = frames_enqueued_ - initial_frames_enqueued; | 146 int frame_delta = frames_enqueued_ - initial_frames_enqueued; |
113 int buffered_delta = algorithm_.frames_buffered() - initial_frames_buffered; | 147 int buffered_delta = algorithm_.frames_buffered() - initial_frames_buffered; |
114 int consumed = frame_delta - buffered_delta; | 148 int consumed = frame_delta - buffered_delta; |
115 CHECK_GE(consumed, 0); | 149 CHECK_GE(consumed, 0); |
116 return consumed; | 150 return consumed; |
117 } | 151 } |
118 | 152 |
119 void TestPlaybackRate(double playback_rate) { | 153 void TestPlaybackRate(double playback_rate) { |
120 const int kDefaultBufferSize = algorithm_.samples_per_second() / 100; | 154 const int kDefaultBufferSize = algorithm_.samples_per_second() / 100; |
121 const int kDefaultFramesRequested = 2 * algorithm_.samples_per_second(); | 155 const int kDefaultFramesRequested = kOutputDurationInSec * |
156 algorithm_.samples_per_second(); | |
122 | 157 |
123 TestPlaybackRate( | 158 TestPlaybackRate( |
124 playback_rate, kDefaultBufferSize, kDefaultFramesRequested); | 159 playback_rate, kDefaultBufferSize, kDefaultFramesRequested); |
125 } | 160 } |
126 | 161 |
127 void TestPlaybackRate(double playback_rate, | 162 void TestPlaybackRate(double playback_rate, |
128 int buffer_size_in_frames, | 163 int buffer_size_in_frames, |
129 int total_frames_requested) { | 164 int total_frames_requested) { |
130 int initial_frames_enqueued = frames_enqueued_; | 165 int initial_frames_enqueued = frames_enqueued_; |
131 int initial_frames_buffered = algorithm_.frames_buffered(); | 166 int initial_frames_buffered = algorithm_.frames_buffered(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 // large, one can expect less than a 1% difference in most cases. In our | 203 // large, one can expect less than a 1% difference in most cases. In our |
169 // current implementation, sped up playback is less accurate than slowed | 204 // current implementation, sped up playback is less accurate than slowed |
170 // down playback, and for playback_rate > 1, playback rate generally gets | 205 // down playback, and for playback_rate > 1, playback rate generally gets |
171 // less and less accurate the farther it drifts from 1 (though this is | 206 // less and less accurate the farther it drifts from 1 (though this is |
172 // nonlinear). | 207 // nonlinear). |
173 double actual_playback_rate = | 208 double actual_playback_rate = |
174 1.0 * frames_consumed / total_frames_requested; | 209 1.0 * frames_consumed / total_frames_requested; |
175 EXPECT_NEAR(playback_rate, actual_playback_rate, playback_rate / 100.0); | 210 EXPECT_NEAR(playback_rate, actual_playback_rate, playback_rate / 100.0); |
176 } | 211 } |
177 | 212 |
213 void WsolaTest(float playback_rate) { | |
214 const int kSampleRateHz = 48000; | |
215 const media::ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; | |
216 const int kBytesPerSample = 2; | |
217 const int kNumFrames = kSampleRateHz / 100; // 10 milliseconds. | |
218 | |
219 channels_ = ChannelLayoutToChannelCount(kChannelLayout); | |
220 AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, | |
221 kSampleRateHz, kBytesPerSample * 8, kNumFrames); | |
222 algorithm_.Initialize(playback_rate, params); | |
223 | |
224 // A pulse is 6 milliseconds (even number of samples). | |
225 const int kPulseWidthSamples = 6 * kSampleRateHz / 1000; | |
226 const int kHalfPulseWidthSamples = kPulseWidthSamples / 2; | |
227 | |
228 // For the ease of implementation get 1 frame every call to FillBuffer(). | |
229 scoped_ptr<AudioBus> output = AudioBus::Create(channels_, 1); | |
230 | |
231 scoped_ptr<AudioBus> ref = | |
232 AudioBus::Create(channels_, kPulseWidthSamples); | |
233 | |
234 FillWithSquarePulseTrain(kHalfPulseWidthSamples, 0, 0, ref.get()); | |
235 FillWithSquarePulseTrain(kHalfPulseWidthSamples, kHalfPulseWidthSamples, 1, | |
236 ref.get()); | |
237 | |
238 const int all_channels_samples = channels_ * kPulseWidthSamples; | |
239 scoped_ptr<int16_t[]> ref_memory_buffer(new int16_t[all_channels_samples]); | |
240 uint8_t* pp[] = { reinterpret_cast<uint8_t*>(ref_memory_buffer.get()) }; | |
241 | |
242 ref->ToInterleaved(kPulseWidthSamples, sizeof(*(ref_memory_buffer.get())), | |
DaleCurtis
2013/08/13 21:11:04
Is it necessary to convert to int16? The AudioBuff
turaj
2013/08/16 22:13:56
I looked at the implementation of AudioBus::ToInte
DaleCurtis
2013/08/19 22:15:23
Do you need the data to be interleaved? It seems
turaj
2013/08/21 01:01:19
I believe I have a better solution.
On 2013/08/19
| |
243 ref_memory_buffer.get()); | |
244 | |
245 base::TimeDelta timestamp = base::TimeDelta::FromInternalValue(0); | |
DaleCurtis
2013/08/13 21:11:04
const these two.
turaj
2013/08/16 22:13:56
Done.
| |
246 base::TimeDelta duration = base::TimeDelta::FromInternalValue(5000); | |
247 | |
248 // |input| has a whole pulse, therefore, we can inject it | |
249 // into |algorithm_| multiple of times to create a periodic input. | |
250 scoped_refptr<AudioBuffer> input = AudioBuffer::CopyFrom( | |
DaleCurtis
2013/08/13 21:11:04
Technically you should be able to create an AudioB
turaj
2013/08/16 22:13:56
I guess you are pointing to WrapMemory(), the pain
DaleCurtis
2013/08/19 22:15:23
AudioBuffer alignment should take care of this for
turaj
2013/08/21 01:01:19
I guess the current implementation is simpler. Tha
| |
251 kSampleFormatS16, channels_, kPulseWidthSamples, pp, timestamp, | |
252 duration); | |
253 | |
254 // Equivalent of 4 seconds. | |
255 const int kNumRequestedPulses = kSampleRateHz * 4 / kPulseWidthSamples; | |
256 for (int n = 0; n < kNumRequestedPulses; ++n) { | |
257 // The output is buffered here until we have a pulse is created. Then | |
258 // reference file is compared with this buffer. | |
259 scoped_ptr<AudioBus> out_buffer = | |
DaleCurtis
2013/08/13 21:11:04
Don't recreate inside loop. Also what's the diffe
turaj
2013/08/16 22:13:56
Done.
| |
260 AudioBus::Create(channels_, kPulseWidthSamples); | |
261 | |
262 int num_buffered_frames = 0; | |
263 while (num_buffered_frames < kPulseWidthSamples) { | |
264 int num_samples = algorithm_.FillBuffer(output.get(), 1); | |
265 EXPECT_LE(num_samples, 1); | |
266 if (num_samples > 0) { | |
267 output->CopyPartialFramesTo(0, num_samples, num_buffered_frames, | |
268 out_buffer.get()); | |
269 num_buffered_frames++; | |
270 } else { | |
271 algorithm_.EnqueueBuffer(input); | |
272 } | |
273 } | |
274 | |
275 // Pulses in the first half of WSOLA AOL frame are not constructed | |
DaleCurtis
2013/08/13 21:11:04
Is this a bug? Will glitches be heard?
turaj
2013/08/16 22:13:56
No this is not a bug. WSOLA is overlap-and-add bas
| |
276 // perfectly. Do not check them. | |
277 if (n > 3) { | |
278 scoped_ptr<int16_t[]> test_memory_buffer( | |
DaleCurtis
2013/08/13 21:11:04
Again, don't allocate inside of the loops. Alloca
turaj
2013/08/16 22:13:56
Done.
| |
279 new int16_t[all_channels_samples]); | |
280 out_buffer->ToInterleaved(kPulseWidthSamples, | |
281 sizeof(*(test_memory_buffer.get())), | |
282 test_memory_buffer.get()); | |
283 | |
284 // Because of overlap-and-add we might have round off error. | |
285 for (int k = 0; k < all_channels_samples - 1; ++k) { | |
286 ASSERT_NEAR(ref_memory_buffer[k], test_memory_buffer[k], 1) | |
287 << " loop " << n << " at sample " << k; | |
288 } | |
289 } | |
290 | |
291 // Zero out the buffer to be sure the next comparison is relevant. | |
292 out_buffer->Zero(); | |
293 } | |
294 } | |
295 | |
178 protected: | 296 protected: |
179 AudioRendererAlgorithm algorithm_; | 297 AudioRendererAlgorithm algorithm_; |
180 int frames_enqueued_; | 298 int frames_enqueued_; |
181 int channels_; | 299 int channels_; |
182 SampleFormat sample_format_; | 300 SampleFormat sample_format_; |
183 int bytes_per_sample_; | 301 int bytes_per_sample_; |
184 }; | 302 }; |
185 | 303 |
186 TEST_F(AudioRendererAlgorithmTest, FillBuffer_NormalRate) { | 304 TEST_F(AudioRendererAlgorithmTest, FillBuffer_NormalRate) { |
187 Initialize(); | 305 Initialize(); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 TestPlaybackRate(2.1); | 381 TestPlaybackRate(2.1); |
264 TestPlaybackRate(0.9); | 382 TestPlaybackRate(0.9); |
265 TestPlaybackRate(0.6); | 383 TestPlaybackRate(0.6); |
266 TestPlaybackRate(1.4); | 384 TestPlaybackRate(1.4); |
267 TestPlaybackRate(0.3); | 385 TestPlaybackRate(0.3); |
268 } | 386 } |
269 | 387 |
270 TEST_F(AudioRendererAlgorithmTest, FillBuffer_SmallBufferSize) { | 388 TEST_F(AudioRendererAlgorithmTest, FillBuffer_SmallBufferSize) { |
271 Initialize(); | 389 Initialize(); |
272 static const int kBufferSizeInFrames = 1; | 390 static const int kBufferSizeInFrames = 1; |
273 static const int kFramesRequested = 2 * kSamplesPerSecond; | 391 static const int kFramesRequested = kOutputDurationInSec * kSamplesPerSecond; |
274 TestPlaybackRate(1.0, kBufferSizeInFrames, kFramesRequested); | 392 TestPlaybackRate(1.0, kBufferSizeInFrames, kFramesRequested); |
275 TestPlaybackRate(0.5, kBufferSizeInFrames, kFramesRequested); | 393 TestPlaybackRate(0.5, kBufferSizeInFrames, kFramesRequested); |
276 TestPlaybackRate(1.5, kBufferSizeInFrames, kFramesRequested); | 394 TestPlaybackRate(1.5, kBufferSizeInFrames, kFramesRequested); |
277 } | 395 } |
278 | 396 |
279 TEST_F(AudioRendererAlgorithmTest, FillBuffer_LargeBufferSize) { | 397 TEST_F(AudioRendererAlgorithmTest, FillBuffer_LargeBufferSize) { |
280 Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, 44100); | 398 Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, 44100); |
281 TestPlaybackRate(1.0); | 399 TestPlaybackRate(1.0); |
282 TestPlaybackRate(0.5); | 400 TestPlaybackRate(0.5); |
283 TestPlaybackRate(1.5); | 401 TestPlaybackRate(1.5); |
284 } | 402 } |
285 | 403 |
286 TEST_F(AudioRendererAlgorithmTest, FillBuffer_LowerQualityAudio) { | 404 TEST_F(AudioRendererAlgorithmTest, FillBuffer_LowerQualityAudio) { |
287 Initialize(CHANNEL_LAYOUT_MONO, kSampleFormatU8, kSamplesPerSecond); | 405 Initialize(CHANNEL_LAYOUT_MONO, kSampleFormatU8, kSamplesPerSecond); |
288 TestPlaybackRate(1.0); | 406 TestPlaybackRate(1.0); |
289 TestPlaybackRate(0.5); | 407 TestPlaybackRate(0.5); |
290 TestPlaybackRate(1.5); | 408 TestPlaybackRate(1.5); |
291 } | 409 } |
292 | 410 |
293 TEST_F(AudioRendererAlgorithmTest, FillBuffer_HigherQualityAudio) { | 411 TEST_F(AudioRendererAlgorithmTest, FillBuffer_HigherQualityAudio) { |
294 Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS32, kSamplesPerSecond); | 412 Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS32, kSamplesPerSecond); |
295 TestPlaybackRate(1.0); | 413 TestPlaybackRate(1.0); |
296 TestPlaybackRate(0.5); | 414 TestPlaybackRate(0.5); |
297 TestPlaybackRate(1.5); | 415 TestPlaybackRate(1.5); |
298 } | 416 } |
299 | 417 |
418 TEST_F(AudioRendererAlgorithmTest, DotProduct) { | |
419 const int kChannels = 3; | |
420 const int kFrames = 20; | |
421 const int kHalfPulseWidth = 2; | |
422 | |
423 scoped_ptr<AudioBus> a = AudioBus::Create(kChannels, kFrames); | |
424 scoped_ptr<AudioBus> b = AudioBus::Create(kChannels, kFrames); | |
425 | |
426 scoped_ptr<float[]> dot_prod(new float[kChannels]); | |
427 | |
428 FillWithSquarePulseTrain(kHalfPulseWidth, 0, 0, a.get()); | |
429 FillWithSquarePulseTrain(kHalfPulseWidth, 1, 1, a.get()); | |
430 FillWithSquarePulseTrain(kHalfPulseWidth, 2, 2, a.get()); | |
431 | |
432 FillWithSquarePulseTrain(kHalfPulseWidth, 0, 0, b.get()); | |
433 FillWithSquarePulseTrain(kHalfPulseWidth, 0, 1, b.get()); | |
434 FillWithSquarePulseTrain(kHalfPulseWidth, 0, 2, b.get()); | |
435 | |
436 internal::MultiChannelDotProduct(a.get(), 0, b.get(), 0, kFrames, | |
437 dot_prod.get()); | |
438 | |
439 EXPECT_FLOAT_EQ(kFrames, dot_prod[0]); | |
440 EXPECT_FLOAT_EQ(0, dot_prod[1]); | |
441 EXPECT_FLOAT_EQ(-kFrames, dot_prod[2]); | |
442 | |
443 internal::MultiChannelDotProduct(a.get(), 4, b.get(), 8, kFrames / 2, | |
444 dot_prod.get()); | |
445 | |
446 EXPECT_FLOAT_EQ(kFrames / 2, dot_prod[0]); | |
447 EXPECT_FLOAT_EQ(0, dot_prod[1]); | |
448 EXPECT_FLOAT_EQ(-kFrames / 2, dot_prod[2]); | |
449 } | |
450 | |
451 TEST_F(AudioRendererAlgorithmTest, MovingBlockEnergy) { | |
452 const int kChannels = 2; | |
453 const int kFrames = 20; | |
454 const int kFramesPerBlock = 3; | |
455 const int kNumBlocks = kFrames - (kFramesPerBlock - 1); | |
456 scoped_ptr<AudioBus> a = AudioBus::Create(kChannels, kFrames); | |
457 scoped_ptr<float[]> energies(new float[kChannels * kNumBlocks]); | |
458 float* ch_left = a->channel(0); | |
459 float* ch_right = a->channel(1); | |
460 | |
461 // Fill up both channels. | |
462 for (int n = 0; n < kFrames; ++n) { | |
463 ch_left[n] = n; | |
464 ch_right[n] = kFrames - 1 - n; | |
465 } | |
466 | |
467 internal::MultiChannelMovingBlockEnergies(a.get(), kFramesPerBlock, | |
468 energies.get()); | |
469 | |
470 for (int n = 0; n < kNumBlocks; ++n) { | |
DaleCurtis
2013/08/13 21:11:04
Comment on what you're testing here.
turaj
2013/08/16 22:13:56
Done.
| |
471 float expected_energy = 0; | |
472 for (int k = 0; k < kFramesPerBlock; ++k) | |
473 expected_energy += ch_left[n + k] * ch_left[n + k]; | |
474 EXPECT_FLOAT_EQ(expected_energy, energies[2 * n]); | |
475 | |
476 expected_energy = 0; | |
477 for (int k = 0; k < kFramesPerBlock; ++k) | |
478 expected_energy += ch_right[n + k] * ch_right[n + k]; | |
479 EXPECT_FLOAT_EQ(expected_energy, energies[2 * n + 1]); | |
480 } | |
481 } | |
482 | |
483 TEST_F(AudioRendererAlgorithmTest, FullAndDecimatedSearch) { | |
484 const int kFramesInSearchRegion = 12; | |
485 const int kChannels = 2; | |
486 float ch_0[] = {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0}; | |
487 float ch_1[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 1.0, 0.1, 0.0, 0.0}; | |
488 ASSERT_EQ(sizeof(ch_0), sizeof(ch_1)); | |
489 ASSERT_EQ(static_cast<size_t>(kFramesInSearchRegion), | |
490 sizeof(ch_0) / sizeof(*ch_0)); | |
491 scoped_ptr<AudioBus> search_region = AudioBus::CreateWrapper(kChannels); | |
492 | |
493 search_region->SetChannelData(0, ch_0); | |
494 search_region->SetChannelData(1, ch_1); | |
495 search_region->set_frames(kFramesInSearchRegion); | |
496 ASSERT_EQ(kFramesInSearchRegion, search_region->frames()); | |
497 | |
498 const int kFramePerBlock = 4; | |
499 float target_0[] = {1.0, 1.0, 1.0, 0.0}; | |
500 float target_1[] = {0.0, 1.0, 0.1, 1.0}; | |
501 ASSERT_EQ(sizeof(target_0), sizeof(target_1)); | |
502 ASSERT_EQ(static_cast<size_t>(kFramePerBlock), | |
503 sizeof(target_0) / sizeof(*target_0)); | |
504 | |
505 scoped_ptr<AudioBus> target = AudioBus::CreateWrapper(2); | |
506 target->SetChannelData(0, target_0); | |
507 target->SetChannelData(1, target_1); | |
508 target->set_frames(kFramePerBlock); | |
509 ASSERT_EQ(kFramePerBlock, target->frames()); | |
510 | |
511 scoped_ptr<float[]> energy_target(new float[kChannels]); | |
512 | |
513 internal::MultiChannelDotProduct(target.get(), 0, target.get(), 0, | |
514 kFramePerBlock, energy_target.get()); | |
515 | |
516 ASSERT_EQ(3.f, energy_target[0]); | |
517 ASSERT_EQ(2.01f, energy_target[1]); | |
518 | |
519 const int kNumCandidBlocks = kFramesInSearchRegion - (kFramePerBlock - 1); | |
520 scoped_ptr<float[]> energy_candid_blocks(new float[kNumCandidBlocks * | |
521 kChannels]); | |
522 | |
523 internal::MultiChannelMovingBlockEnergies( | |
524 search_region.get(), kFramePerBlock, energy_candid_blocks.get()); | |
525 | |
526 ASSERT_FLOAT_EQ(0, energy_candid_blocks[0]); | |
DaleCurtis
2013/08/13 21:11:04
Comments on what's being tested.
turaj
2013/08/16 22:13:56
Done.
| |
527 ASSERT_FLOAT_EQ(0, energy_candid_blocks[2]); | |
528 ASSERT_FLOAT_EQ(1, energy_candid_blocks[4]); | |
529 ASSERT_FLOAT_EQ(2, energy_candid_blocks[6]); | |
530 ASSERT_FLOAT_EQ(3, energy_candid_blocks[8]); | |
531 ASSERT_FLOAT_EQ(3, energy_candid_blocks[10]); | |
532 ASSERT_FLOAT_EQ(2, energy_candid_blocks[12]); | |
533 ASSERT_FLOAT_EQ(1, energy_candid_blocks[14]); | |
534 ASSERT_FLOAT_EQ(0, energy_candid_blocks[16]); | |
535 | |
536 ASSERT_FLOAT_EQ(0, energy_candid_blocks[1]); | |
537 ASSERT_FLOAT_EQ(0, energy_candid_blocks[3]); | |
538 ASSERT_FLOAT_EQ(0, energy_candid_blocks[5]); | |
539 ASSERT_FLOAT_EQ(0, energy_candid_blocks[7]); | |
540 ASSERT_FLOAT_EQ(0.01, energy_candid_blocks[9]); | |
541 ASSERT_FLOAT_EQ(1.01, energy_candid_blocks[11]); | |
542 ASSERT_FLOAT_EQ(1.02, energy_candid_blocks[13]); | |
543 ASSERT_FLOAT_EQ(1.02, energy_candid_blocks[15]); | |
544 ASSERT_FLOAT_EQ(1.01, energy_candid_blocks[17]); | |
545 | |
546 // An interval which is of no effect. | |
547 internal::Interval exclude_interval = std::make_pair(-100, -10); | |
548 EXPECT_EQ(5, internal::FullSearch( | |
549 0, kNumCandidBlocks - 1, exclude_interval, target.get(), | |
550 search_region.get(), energy_target.get(), energy_candid_blocks.get())); | |
551 | |
552 // Exclude the the best match. | |
553 exclude_interval = std::make_pair(2, 5); | |
554 EXPECT_EQ(7, internal::FullSearch( | |
555 0, kNumCandidBlocks - 1, exclude_interval, target.get(), | |
556 search_region.get(), energy_target.get(), energy_candid_blocks.get())); | |
557 | |
558 // An interval which is of no effect. | |
559 exclude_interval = std::make_pair(-100, -10); | |
560 EXPECT_EQ(4, internal::DecimatedSearch( | |
561 4, exclude_interval, target.get(), search_region.get(), | |
562 energy_target.get(), energy_candid_blocks.get())); | |
563 | |
564 EXPECT_EQ(5, internal::OptimalIndex(search_region.get(), target.get(), | |
565 exclude_interval)); | |
566 } | |
567 | |
568 TEST_F(AudioRendererAlgorithmTest, CubicInterpolation) { | |
569 // Arbitrary coefficients. | |
570 const float kA = 0.7; | |
571 const float kB = 1.2; | |
572 const float kC = 0.8; | |
573 | |
574 float y_values[3]; | |
575 y_values[0] = kA - kB + kC; | |
576 y_values[1] = kC; | |
577 y_values[2] = kA + kB + kC; | |
578 | |
579 float extremum; | |
580 float extremum_value; | |
581 | |
582 internal::CubicInterpolation(y_values, &extremum, &extremum_value); | |
583 | |
584 float x_star = -kB / (2.f * kA); | |
585 float y_star = kA * x_star * x_star + kB * x_star + kC; | |
586 | |
587 EXPECT_FLOAT_EQ(x_star, extremum); | |
588 EXPECT_FLOAT_EQ(y_star, extremum_value); | |
589 } | |
590 | |
591 TEST_F(AudioRendererAlgorithmTest, WsolaSlowdown) { | |
592 WsolaTest(1.6f); | |
593 } | |
594 | |
595 TEST_F(AudioRendererAlgorithmTest, WsolaSpeedup) { | |
596 WsolaTest(0.6f); | |
597 } | |
598 | |
300 } // namespace media | 599 } // namespace media |
OLD | NEW |