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

Side by Side Diff: media/filters/audio_renderer_algorithm_unittest.cc

Issue 19111004: Upgrade AudioRendererAlgorithm to use WSOLA, (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Avoid malloc in every iteration by defining some member varibles. Created 7 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 // 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;
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
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
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())),
243 ref_memory_buffer.get());
244
245 base::TimeDelta timestamp = base::TimeDelta::FromInternalValue(0);
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(
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 =
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
276 // perfectly. Do not check them.
277 if (n > 3) {
278 scoped_ptr<int16_t[]> test_memory_buffer(
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
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, MovingWindowEnergy) {
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::MultiChannelMovingWindowEnergies(a.get(), kFramesPerBlock,
468 energies.get());
469
470 for (int n = 0; n < kNumBlocks; ++n) {
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, PartialAndDecimatedSearch) {
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::MultiChannelMovingWindowEnergies(
524 search_region.get(), kFramePerBlock, energy_candid_blocks.get());
525
526 ASSERT_FLOAT_EQ(0, energy_candid_blocks[0]);
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::PartialSearch(
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::PartialSearch(
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698