Chromium Code Reviews| Index: media/base/sinc_resampler_unittest.cc |
| diff --git a/media/base/sinc_resampler_unittest.cc b/media/base/sinc_resampler_unittest.cc |
| index 9bf7ba4409b97d0ffbdbfbc267f900535df96073..58856eced885f462170cfb4814c8a72287369cf6 100644 |
| --- a/media/base/sinc_resampler_unittest.cc |
| +++ b/media/base/sinc_resampler_unittest.cc |
| @@ -9,9 +9,9 @@ |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| +#include "base/format_macros.h" |
| #include "base/logging.h" |
| -#include "base/memory/scoped_ptr.h" |
| -#include "base/stringprintf.h" |
| +#include "base/time.h" |
| #include "media/base/sinc_resampler.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| @@ -20,6 +20,9 @@ using testing::_; |
| namespace media { |
| +static const double kSampleRateRatio = 192000.0 / 44100.0; |
| +static const double kKernelInterpolationFactor = 0.5; |
| + |
| // Helper class to ensure ChunkedResample() functions properly. |
| class MockSource { |
| public: |
| @@ -33,7 +36,6 @@ TEST(SincResamplerTest, ChunkedResample) { |
| // Choose a high ratio of input to output samples which will result in quick |
| // exhaustion of SincResampler's internal buffers. |
| - static const double kSampleRateRatio = 192000.0 / 44100.0; |
| SincResampler resampler( |
| kSampleRateRatio, |
| base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source))); |
| @@ -52,6 +54,88 @@ TEST(SincResamplerTest, ChunkedResample) { |
| resampler.Resample(resampled_destination.get(), max_chunk_size); |
| } |
| +// Ensure various optimized Convolve() methods return the same value. Only run |
| +// this test if other optimized methods exist, otherwise the default Convolve() |
| +// will be tested by the parameterized SincResampler tests below. |
| +#if defined(ARCH_CPU_X86_FAMILY) && defined(__SSE__) |
| +TEST(SincResamplerTest, Convolve) { |
| + // Initialize a dummy resampler. |
| + MockSource mock_source; |
| + SincResampler resampler( |
| + kSampleRateRatio, |
| + base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source))); |
| + |
| + // Convolve_SSE() is slightly more precise than Conolve_C(), so comparison |
| + // must be done using an epsilon. |
| + static const double kEpsilon = 0.00000005; |
| + |
| + // Use a kernel from SincResampler as input and kernel data, this has the |
| + // benefit of already being properly sized and aligned for Convolve_SSE(). |
| + double result = resampler.Convolve_C( |
| + resampler.kernel_storage_.get(), resampler.kernel_storage_.get(), |
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor); |
| + double result2 = resampler.Convolve_SSE( |
| + resampler.kernel_storage_.get(), resampler.kernel_storage_.get(), |
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor); |
| + EXPECT_NEAR(result2, result, kEpsilon); |
| + |
| + // Test Convolve_SSE() w/ unaligned input pointer. |
| + result = resampler.Convolve_C( |
| + resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(), |
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor); |
| + result2 = resampler.Convolve_SSE( |
| + resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(), |
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor); |
| + EXPECT_NEAR(result2, result, kEpsilon); |
| +} |
| +#endif |
| + |
| +// Benchmark for the various Convolve() methods. |
|
Ami GONE FROM CHROMIUM
2012/07/21 17:25:10
Comment that this is only DISABLED_ for the benefi
DaleCurtis
2012/07/24 00:13:07
Done. --convolve-iterations is runtime settable.
|
| +TEST(SincResamplerTest, DISABLED_ConvolveBenchmark) { |
| + // Initialize a dummy resampler. |
| + MockSource mock_source; |
| + SincResampler resampler( |
| + kSampleRateRatio, |
| + base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source))); |
| + |
| + static const int kConvolveIterations = 50000000; |
| + |
| + // Benchmark Convolve_C(). |
| + base::TimeTicks start = base::TimeTicks::HighResNow(); |
| + for (int i = 0; i < kConvolveIterations; ++i) { |
| + resampler.Convolve_C( |
| + resampler.kernel_storage_.get(), resampler.kernel_storage_.get(), |
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor); |
| + } |
| + base::TimeTicks end = base::TimeTicks::HighResNow(); |
| + printf("Convolve_C took %" PRId64 "ms for %d iterations.\n", |
| + (end - start).InMilliseconds(), kConvolveIterations); |
| + |
| +#if defined(ARCH_CPU_X86_FAMILY) && defined(__SSE__) |
| + // Benchmark Convolve_SSE() with aligned input pointer. |
| + start = base::TimeTicks::HighResNow(); |
| + for (int j = 0; j < kConvolveIterations; ++j) { |
| + resampler.Convolve_SSE( |
| + resampler.kernel_storage_.get(), resampler.kernel_storage_.get(), |
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor); |
| + } |
| + end = base::TimeTicks::HighResNow(); |
| + printf("Convolve_SSE (aligned) took %" PRId64 "ms for %d iterations.\n", |
| + (end - start).InMilliseconds(), kConvolveIterations); |
| + |
| + // Benchmark Convolve_SSE() with unaligned input pointer. |
| + start = base::TimeTicks::HighResNow(); |
| + for (int j = 0; j < kConvolveIterations; ++j) { |
| + resampler.Convolve_SSE( |
| + resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(), |
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor); |
| + } |
| + end = base::TimeTicks::HighResNow(); |
| + printf("Convolve_SSE (unaligned) took %" PRId64 "ms for %d iterations.\n", |
| + (end - start).InMilliseconds(), kConvolveIterations); |
| +#endif |
|
Ami GONE FROM CHROMIUM
2012/07/21 17:25:10
Add an output for the relative improvement between
DaleCurtis
2012/07/24 00:13:07
Done.
|
| +} |
| + |
| // Fake audio source for testing the resampler. Generates a sinusoidal linear |
| // chirp (http://en.wikipedia.org/wiki/Chirp) which can be tuned to stress the |
| // resampler for the specific sample rate conversion being used. |