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

Unified Diff: media/base/sinc_resampler_unittest.cc

Issue 19470003: DO NOT COMMIT. Diff of downstream webrtc resampler commit for review purposes. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/sinc_resampler.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/sinc_resampler_unittest.cc
diff --git a/media/base/sinc_resampler_unittest.cc b/media/base/sinc_resampler_unittest.cc
index 8b89a5d3808034ab4d5ad705b8f0c6fd311cde41..b228f3d419a049320ce6e00285ab5816e0c9181b 100644
--- a/media/base/sinc_resampler_unittest.cc
+++ b/media/base/sinc_resampler_unittest.cc
@@ -1,39 +1,42 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+/*
+ * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// Modified from the Chromium original:
+// src/media/base/sinc_resampler_unittest.cc
// MSVC++ requires this to be set before any other includes to get M_PI.
#define _USE_MATH_DEFINES
#include <cmath>
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/cpu.h"
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringize_macros.h"
-#include "base/time/time.h"
-#include "build/build_config.h"
-#include "media/base/sinc_resampler.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/common_audio/resampler/sinc_resampler.h"
+#include "webrtc/common_audio/resampler/sinusoidal_linear_chirp_source.h"
+#include "webrtc/system_wrappers/interface/cpu_features_wrapper.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+#include "webrtc/system_wrappers/interface/stringize_macros.h"
+#include "webrtc/system_wrappers/interface/tick_util.h"
+#include "webrtc/test/test_suite.h"
using testing::_;
-namespace media {
+namespace webrtc {
static const double kSampleRateRatio = 192000.0 / 44100.0;
static const double kKernelInterpolationFactor = 0.5;
-// Command line switch for runtime adjustment of ConvolveBenchmark iterations.
-static const char kConvolveIterations[] = "convolve-iterations";
-
// Helper class to ensure ChunkedResample() functions properly.
-class MockSource {
+class MockSource : public SincResamplerCallback {
public:
- MOCK_METHOD2(ProvideInput, void(int frames, float* destination));
+ MOCK_METHOD2(Run, void(int frames, float* destination));
};
ACTION(ClearBuffer) {
@@ -54,22 +57,21 @@ TEST(SincResamplerTest, ChunkedResample) {
// Choose a high ratio of input to output samples which will result in quick
// exhaustion of SincResampler's internal buffers.
- SincResampler resampler(
- kSampleRateRatio, SincResampler::kDefaultRequestSize,
- base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source)));
+ SincResampler resampler(kSampleRateRatio, SincResampler::kDefaultRequestSize,
+ &mock_source);
static const int kChunks = 2;
int max_chunk_size = resampler.ChunkSize() * kChunks;
- scoped_ptr<float[]> resampled_destination(new float[max_chunk_size]);
+ scoped_array<float> resampled_destination(new float[max_chunk_size]);
// Verify requesting ChunkSize() frames causes a single callback.
- EXPECT_CALL(mock_source, ProvideInput(_, _))
+ EXPECT_CALL(mock_source, Run(_, _))
.Times(1).WillOnce(ClearBuffer());
resampler.Resample(resampler.ChunkSize(), resampled_destination.get());
// Verify requesting kChunks * ChunkSize() frames causes kChunks callbacks.
testing::Mock::VerifyAndClear(&mock_source);
- EXPECT_CALL(mock_source, ProvideInput(_, _))
+ EXPECT_CALL(mock_source, Run(_, _))
.Times(kChunks).WillRepeatedly(ClearBuffer());
resampler.Resample(max_chunk_size, resampled_destination.get());
}
@@ -77,13 +79,12 @@ TEST(SincResamplerTest, ChunkedResample) {
// Test flush resets the internal state properly.
TEST(SincResamplerTest, Flush) {
MockSource mock_source;
- SincResampler resampler(
- kSampleRateRatio, SincResampler::kDefaultRequestSize,
- base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source)));
- scoped_ptr<float[]> resampled_destination(new float[resampler.ChunkSize()]);
+ SincResampler resampler(kSampleRateRatio, SincResampler::kDefaultRequestSize,
+ &mock_source);
+ scoped_array<float> resampled_destination(new float[resampler.ChunkSize()]);
// Fill the resampler with junk data.
- EXPECT_CALL(mock_source, ProvideInput(_, _))
+ EXPECT_CALL(mock_source, Run(_, _))
.Times(1).WillOnce(FillBuffer());
resampler.Resample(resampler.ChunkSize() / 2, resampled_destination.get());
ASSERT_NE(resampled_destination[0], 0);
@@ -91,7 +92,7 @@ TEST(SincResamplerTest, Flush) {
// Flush and request more data, which should all be zeros now.
resampler.Flush();
testing::Mock::VerifyAndClear(&mock_source);
- EXPECT_CALL(mock_source, ProvideInput(_, _))
+ EXPECT_CALL(mock_source, Run(_, _))
.Times(1).WillOnce(ClearBuffer());
resampler.Resample(resampler.ChunkSize() / 2, resampled_destination.get());
for (int i = 0; i < resampler.ChunkSize() / 2; ++i)
@@ -101,23 +102,21 @@ TEST(SincResamplerTest, Flush) {
// Test flush resets the internal state properly.
TEST(SincResamplerTest, DISABLED_SetRatioBench) {
MockSource mock_source;
- SincResampler resampler(
- kSampleRateRatio, SincResampler::kDefaultRequestSize,
- base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source)));
+ SincResampler resampler(kSampleRateRatio, SincResampler::kDefaultRequestSize,
+ &mock_source);
- base::TimeTicks start = base::TimeTicks::HighResNow();
+ TickTime start = TickTime::Now();
for (int i = 1; i < 10000; ++i)
resampler.SetRatio(1.0 / i);
- double total_time_c_ms =
- (base::TimeTicks::HighResNow() - start).InMillisecondsF();
- printf("SetRatio() took %.2fms.\n", total_time_c_ms);
+ double total_time_c_us = (TickTime::Now() - start).Microseconds();
+ printf("SetRatio() took %.2fms.\n", total_time_c_us / 1000);
}
// Define platform independent function name for Convolve* tests.
-#if defined(ARCH_CPU_X86_FAMILY)
+#if defined(WEBRTC_ARCH_X86_FAMILY)
#define CONVOLVE_FUNC Convolve_SSE
-#elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON)
+#elif defined(WEBRTC_ARCH_ARM_V7)
#define CONVOLVE_FUNC Convolve_NEON
#endif
@@ -126,15 +125,16 @@ TEST(SincResamplerTest, DISABLED_SetRatioBench) {
// will be tested by the parameterized SincResampler tests below.
#if defined(CONVOLVE_FUNC)
TEST(SincResamplerTest, Convolve) {
-#if defined(ARCH_CPU_X86_FAMILY)
- ASSERT_TRUE(base::CPU().has_sse());
+#if defined(WEBRTC_ARCH_X86_FAMILY)
+ ASSERT_TRUE(WebRtc_GetCPUInfo(kSSE2));
+#elif defined(WEBRTC_ARCH_ARM_V7)
+ ASSERT_TRUE(WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON);
#endif
// Initialize a dummy resampler.
MockSource mock_source;
- SincResampler resampler(
- kSampleRateRatio, SincResampler::kDefaultRequestSize,
- base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source)));
+ SincResampler resampler(kSampleRateRatio, SincResampler::kDefaultRequestSize,
+ &mock_source);
// The optimized Convolve methods are slightly more precise than Convolve_C(),
// so comparison must be done using an epsilon.
@@ -167,121 +167,65 @@ TEST(SincResamplerTest, Convolve) {
TEST(SincResamplerTest, ConvolveBenchmark) {
// Initialize a dummy resampler.
MockSource mock_source;
- SincResampler resampler(
- kSampleRateRatio, SincResampler::kDefaultRequestSize,
- base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source)));
+ SincResampler resampler(kSampleRateRatio, SincResampler::kDefaultRequestSize,
+ &mock_source);
// Retrieve benchmark iterations from command line.
- int convolve_iterations = 10;
- std::string iterations(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- kConvolveIterations));
- if (!iterations.empty())
- base::StringToInt(iterations, &convolve_iterations);
+ // TODO(ajm): Reintroduce this as a command line option.
+ const int kConvolveIterations = 1000000;
- printf("Benchmarking %d iterations:\n", convolve_iterations);
+ printf("Benchmarking %d iterations:\n", kConvolveIterations);
// Benchmark Convolve_C().
- base::TimeTicks start = base::TimeTicks::HighResNow();
- for (int i = 0; i < convolve_iterations; ++i) {
+ TickTime start = TickTime::Now();
+ for (int i = 0; i < kConvolveIterations; ++i) {
resampler.Convolve_C(
resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
resampler.kernel_storage_.get(), kKernelInterpolationFactor);
}
- double total_time_c_ms =
- (base::TimeTicks::HighResNow() - start).InMillisecondsF();
- printf("Convolve_C took %.2fms.\n", total_time_c_ms);
+ double total_time_c_us = (TickTime::Now() - start).Microseconds();
+ printf("Convolve_C took %.2fms.\n", total_time_c_us / 1000);
#if defined(CONVOLVE_FUNC)
-#if defined(ARCH_CPU_X86_FAMILY)
- ASSERT_TRUE(base::CPU().has_sse());
+#if defined(WEBRTC_ARCH_X86_FAMILY)
+ ASSERT_TRUE(WebRtc_GetCPUInfo(kSSE2));
+#elif defined(WEBRTC_ARCH_ARM_V7)
+ ASSERT_TRUE(WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON);
#endif
// Benchmark with unaligned input pointer.
- start = base::TimeTicks::HighResNow();
- for (int j = 0; j < convolve_iterations; ++j) {
+ start = TickTime::Now();
+ for (int j = 0; j < kConvolveIterations; ++j) {
resampler.CONVOLVE_FUNC(
resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(),
resampler.kernel_storage_.get(), kKernelInterpolationFactor);
}
- double total_time_optimized_unaligned_ms =
- (base::TimeTicks::HighResNow() - start).InMillisecondsF();
- printf(STRINGIZE(CONVOLVE_FUNC) " (unaligned) took %.2fms; which is %.2fx "
- "faster than Convolve_C.\n", total_time_optimized_unaligned_ms,
- total_time_c_ms / total_time_optimized_unaligned_ms);
+ double total_time_optimized_unaligned_us =
+ (TickTime::Now() - start).Microseconds();
+ printf(STRINGIZE(CONVOLVE_FUNC) "(unaligned) took %.2fms; which is %.2fx "
+ "faster than Convolve_C.\n", total_time_optimized_unaligned_us / 1000,
+ total_time_c_us / total_time_optimized_unaligned_us);
// Benchmark with aligned input pointer.
- start = base::TimeTicks::HighResNow();
- for (int j = 0; j < convolve_iterations; ++j) {
+ start = TickTime::Now();
+ for (int j = 0; j < kConvolveIterations; ++j) {
resampler.CONVOLVE_FUNC(
resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
resampler.kernel_storage_.get(), kKernelInterpolationFactor);
}
- double total_time_optimized_aligned_ms =
- (base::TimeTicks::HighResNow() - start).InMillisecondsF();
+ double total_time_optimized_aligned_us =
+ (TickTime::Now() - start).Microseconds();
printf(STRINGIZE(CONVOLVE_FUNC) " (aligned) took %.2fms; which is %.2fx "
"faster than Convolve_C and %.2fx faster than "
STRINGIZE(CONVOLVE_FUNC) " (unaligned).\n",
- total_time_optimized_aligned_ms,
- total_time_c_ms / total_time_optimized_aligned_ms,
- total_time_optimized_unaligned_ms / total_time_optimized_aligned_ms);
+ total_time_optimized_aligned_us / 1000,
+ total_time_c_us / total_time_optimized_aligned_us,
+ total_time_optimized_unaligned_us / total_time_optimized_aligned_us);
#endif
}
#undef CONVOLVE_FUNC
-// 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.
-class SinusoidalLinearChirpSource {
- public:
- SinusoidalLinearChirpSource(int sample_rate,
- int samples,
- double max_frequency)
- : sample_rate_(sample_rate),
- total_samples_(samples),
- max_frequency_(max_frequency),
- current_index_(0) {
- // Chirp rate.
- double duration = static_cast<double>(total_samples_) / sample_rate_;
- k_ = (max_frequency_ - kMinFrequency) / duration;
- }
-
- virtual ~SinusoidalLinearChirpSource() {}
-
- void ProvideInput(int frames, float* destination) {
- for (int i = 0; i < frames; ++i, ++current_index_) {
- // Filter out frequencies higher than Nyquist.
- if (Frequency(current_index_) > 0.5 * sample_rate_) {
- destination[i] = 0;
- } else {
- // Calculate time in seconds.
- double t = static_cast<double>(current_index_) / sample_rate_;
-
- // Sinusoidal linear chirp.
- destination[i] = sin(2 * M_PI * (kMinFrequency * t + (k_ / 2) * t * t));
- }
- }
- }
-
- double Frequency(int position) {
- return kMinFrequency + position * (max_frequency_ - kMinFrequency)
- / total_samples_;
- }
-
- private:
- enum {
- kMinFrequency = 5
- };
-
- double sample_rate_;
- int total_samples_;
- double max_frequency_;
- double k_;
- int current_index_;
-
- DISALLOW_COPY_AND_ASSIGN(SinusoidalLinearChirpSource);
-};
-
typedef std::tr1::tuple<int, int, double, double> SincResamplerTestData;
class SincResamplerTest
: public testing::TestWithParam<SincResamplerTestData> {
@@ -306,25 +250,23 @@ class SincResamplerTest
TEST_P(SincResamplerTest, Resample) {
// Make comparisons using one second of data.
static const double kTestDurationSecs = 1;
- int input_samples = kTestDurationSecs * input_rate_;
- int output_samples = kTestDurationSecs * output_rate_;
+ const int input_samples = kTestDurationSecs * input_rate_;
+ const int output_samples = kTestDurationSecs * output_rate_;
// Nyquist frequency for the input sampling rate.
- double input_nyquist_freq = 0.5 * input_rate_;
+ const double input_nyquist_freq = 0.5 * input_rate_;
// Source for data to be resampled.
SinusoidalLinearChirpSource resampler_source(
- input_rate_, input_samples, input_nyquist_freq);
+ input_rate_, input_samples, input_nyquist_freq, 0);
const double io_ratio = input_rate_ / static_cast<double>(output_rate_);
- SincResampler resampler(
- io_ratio, SincResampler::kDefaultRequestSize,
- base::Bind(&SinusoidalLinearChirpSource::ProvideInput,
- base::Unretained(&resampler_source)));
+ SincResampler resampler(io_ratio, SincResampler::kDefaultRequestSize,
+ &resampler_source);
// Force an update to the sample rate ratio to ensure dyanmic sample rate
// changes are working correctly.
- scoped_ptr<float[]> kernel(new float[SincResampler::kKernelStorageSize]);
+ scoped_array<float> kernel(new float[SincResampler::kKernelStorageSize]);
memcpy(kernel.get(), resampler.get_kernel_for_testing(),
SincResampler::kKernelStorageSize);
resampler.SetRatio(M_PI);
@@ -336,16 +278,16 @@ TEST_P(SincResamplerTest, Resample) {
// TODO(dalecurtis): If we switch to AVX/SSE optimization, we'll need to
// allocate these on 32-byte boundaries and ensure they're sized % 32 bytes.
- scoped_ptr<float[]> resampled_destination(new float[output_samples]);
- scoped_ptr<float[]> pure_destination(new float[output_samples]);
+ scoped_array<float> resampled_destination(new float[output_samples]);
+ scoped_array<float> pure_destination(new float[output_samples]);
// Generate resampled signal.
resampler.Resample(output_samples, resampled_destination.get());
// Generate pure signal.
SinusoidalLinearChirpSource pure_source(
- output_rate_, output_samples, input_nyquist_freq);
- pure_source.ProvideInput(output_samples, pure_destination.get());
+ output_rate_, output_samples, input_nyquist_freq, 0);
+ pure_source.Run(output_samples, pure_destination.get());
// Range of the Nyquist frequency (0.5 * min(input rate, output_rate)) which
// we refer to as low and high.
@@ -441,4 +383,4 @@ INSTANTIATE_TEST_CASE_P(
std::tr1::make_tuple(96000, 192000, kResamplingRMSError, -73.52),
std::tr1::make_tuple(192000, 192000, kResamplingRMSError, -73.52)));
-} // namespace media
+} // namespace webrtc
« no previous file with comments | « media/base/sinc_resampler.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698