blob: 990580dd2da298dfd0aa1f74e9de7e7e75b59db5 [file] [log] [blame]
andrew@webrtc.org076fc122013-02-15 03:54:22 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11// Modified from the Chromium original:
12// src/media/base/sinc_resampler_unittest.cc
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000013
andrew@webrtc.orgc6a37552013-05-08 20:35:43 +000014// MSVC++ requires this to be set before any other includes to get M_PI.
15#define _USE_MATH_DEFINES
16
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000017#include <math.h>
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000018
oprypin67fdb802017-03-09 06:25:06 -080019#include <algorithm>
kwibergc2b785d2016-02-24 05:22:32 -080020#include <memory>
21
kjellandered754e72017-04-19 08:37:36 -070022#include "webrtc/base/stringize_macros.h"
Niels Möllerd28db7f2016-05-10 16:31:47 +020023#include "webrtc/base/timeutils.h"
andrew@webrtc.org076fc122013-02-15 03:54:22 +000024#include "webrtc/common_audio/resampler/sinc_resampler.h"
andrew@webrtc.org8fc05fe2013-04-26 14:56:51 +000025#include "webrtc/common_audio/resampler/sinusoidal_linear_chirp_source.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010026#include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
kwibergac9f8762016-09-30 22:29:43 -070027#include "webrtc/test/gmock.h"
28#include "webrtc/test/gtest.h"
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000029
30using testing::_;
31
andrew@webrtc.org076fc122013-02-15 03:54:22 +000032namespace webrtc {
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000033
34static const double kSampleRateRatio = 192000.0 / 44100.0;
35static const double kKernelInterpolationFactor = 0.5;
36
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000037// Helper class to ensure ChunkedResample() functions properly.
andrew@webrtc.org076fc122013-02-15 03:54:22 +000038class MockSource : public SincResamplerCallback {
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000039 public:
Peter Kastingdce40cf2015-08-24 14:52:23 -070040 MOCK_METHOD2(Run, void(size_t frames, float* destination));
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000041};
42
43ACTION(ClearBuffer) {
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +000044 memset(arg1, 0, arg0 * sizeof(float));
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000045}
46
47ACTION(FillBuffer) {
48 // Value chosen arbitrarily such that SincResampler resamples it to something
49 // easily representable on all platforms; e.g., using kSampleRateRatio this
50 // becomes 1.81219.
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +000051 memset(arg1, 64, arg0 * sizeof(float));
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000052}
53
54// Test requesting multiples of ChunkSize() frames results in the proper number
55// of callbacks.
56TEST(SincResamplerTest, ChunkedResample) {
57 MockSource mock_source;
58
59 // Choose a high ratio of input to output samples which will result in quick
60 // exhaustion of SincResampler's internal buffers.
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +000061 SincResampler resampler(kSampleRateRatio, SincResampler::kDefaultRequestSize,
62 &mock_source);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000063
64 static const int kChunks = 2;
Peter Kastingdce40cf2015-08-24 14:52:23 -070065 size_t max_chunk_size = resampler.ChunkSize() * kChunks;
kwibergc2b785d2016-02-24 05:22:32 -080066 std::unique_ptr<float[]> resampled_destination(new float[max_chunk_size]);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000067
68 // Verify requesting ChunkSize() frames causes a single callback.
andrew@webrtc.org076fc122013-02-15 03:54:22 +000069 EXPECT_CALL(mock_source, Run(_, _))
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000070 .Times(1).WillOnce(ClearBuffer());
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +000071 resampler.Resample(resampler.ChunkSize(), resampled_destination.get());
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000072
73 // Verify requesting kChunks * ChunkSize() frames causes kChunks callbacks.
74 testing::Mock::VerifyAndClear(&mock_source);
andrew@webrtc.org076fc122013-02-15 03:54:22 +000075 EXPECT_CALL(mock_source, Run(_, _))
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000076 .Times(kChunks).WillRepeatedly(ClearBuffer());
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +000077 resampler.Resample(max_chunk_size, resampled_destination.get());
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000078}
79
80// Test flush resets the internal state properly.
81TEST(SincResamplerTest, Flush) {
82 MockSource mock_source;
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +000083 SincResampler resampler(kSampleRateRatio, SincResampler::kDefaultRequestSize,
84 &mock_source);
kwibergc2b785d2016-02-24 05:22:32 -080085 std::unique_ptr<float[]> resampled_destination(
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +000086 new float[resampler.ChunkSize()]);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000087
88 // Fill the resampler with junk data.
andrew@webrtc.org076fc122013-02-15 03:54:22 +000089 EXPECT_CALL(mock_source, Run(_, _))
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000090 .Times(1).WillOnce(FillBuffer());
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +000091 resampler.Resample(resampler.ChunkSize() / 2, resampled_destination.get());
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000092 ASSERT_NE(resampled_destination[0], 0);
93
94 // Flush and request more data, which should all be zeros now.
95 resampler.Flush();
96 testing::Mock::VerifyAndClear(&mock_source);
andrew@webrtc.org076fc122013-02-15 03:54:22 +000097 EXPECT_CALL(mock_source, Run(_, _))
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +000098 .Times(1).WillOnce(ClearBuffer());
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +000099 resampler.Resample(resampler.ChunkSize() / 2, resampled_destination.get());
Peter Kastingdce40cf2015-08-24 14:52:23 -0700100 for (size_t i = 0; i < resampler.ChunkSize() / 2; ++i)
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000101 ASSERT_FLOAT_EQ(resampled_destination[i], 0);
102}
103
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +0000104// Test flush resets the internal state properly.
105TEST(SincResamplerTest, DISABLED_SetRatioBench) {
106 MockSource mock_source;
107 SincResampler resampler(kSampleRateRatio, SincResampler::kDefaultRequestSize,
108 &mock_source);
109
Niels Möllerd28db7f2016-05-10 16:31:47 +0200110 int64_t start = rtc::TimeNanos();
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +0000111 for (int i = 1; i < 10000; ++i)
112 resampler.SetRatio(1.0 / i);
Niels Möllerd28db7f2016-05-10 16:31:47 +0200113 double total_time_c_us =
114 (rtc::TimeNanos() - start) / rtc::kNumNanosecsPerMicrosec;
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +0000115 printf("SetRatio() took %.2fms.\n", total_time_c_us / 1000);
116}
117
118
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000119// Define platform independent function name for Convolve* tests.
andrew@webrtc.orgc6a37552013-05-08 20:35:43 +0000120#if defined(WEBRTC_ARCH_X86_FAMILY)
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000121#define CONVOLVE_FUNC Convolve_SSE
andrew@webrtc.orgc6a37552013-05-08 20:35:43 +0000122#elif defined(WEBRTC_ARCH_ARM_V7)
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000123#define CONVOLVE_FUNC Convolve_NEON
124#endif
125
126// Ensure various optimized Convolve() methods return the same value. Only run
127// this test if other optimized methods exist, otherwise the default Convolve()
128// will be tested by the parameterized SincResampler tests below.
129#if defined(CONVOLVE_FUNC)
130TEST(SincResamplerTest, Convolve) {
andrew@webrtc.orgc6a37552013-05-08 20:35:43 +0000131#if defined(WEBRTC_ARCH_X86_FAMILY)
132 ASSERT_TRUE(WebRtc_GetCPUInfo(kSSE2));
133#elif defined(WEBRTC_ARCH_ARM_V7)
134 ASSERT_TRUE(WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON);
135#endif
136
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000137 // Initialize a dummy resampler.
138 MockSource mock_source;
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +0000139 SincResampler resampler(kSampleRateRatio, SincResampler::kDefaultRequestSize,
140 &mock_source);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000141
142 // The optimized Convolve methods are slightly more precise than Convolve_C(),
143 // so comparison must be done using an epsilon.
144 static const double kEpsilon = 0.00000005;
145
146 // Use a kernel from SincResampler as input and kernel data, this has the
147 // benefit of already being properly sized and aligned for Convolve_SSE().
148 double result = resampler.Convolve_C(
149 resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
150 resampler.kernel_storage_.get(), kKernelInterpolationFactor);
151 double result2 = resampler.CONVOLVE_FUNC(
152 resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
153 resampler.kernel_storage_.get(), kKernelInterpolationFactor);
154 EXPECT_NEAR(result2, result, kEpsilon);
155
156 // Test Convolve() w/ unaligned input pointer.
157 result = resampler.Convolve_C(
158 resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(),
159 resampler.kernel_storage_.get(), kKernelInterpolationFactor);
160 result2 = resampler.CONVOLVE_FUNC(
161 resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(),
162 resampler.kernel_storage_.get(), kKernelInterpolationFactor);
163 EXPECT_NEAR(result2, result, kEpsilon);
164}
165#endif
166
167// Benchmark for the various Convolve() methods. Make sure to build with
henrikg91d6ede2015-09-17 00:24:34 -0700168// branding=Chrome so that RTC_DCHECKs are compiled out when benchmarking.
169// Original benchmarks were run with --convolve-iterations=50000000.
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000170TEST(SincResamplerTest, ConvolveBenchmark) {
171 // Initialize a dummy resampler.
172 MockSource mock_source;
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +0000173 SincResampler resampler(kSampleRateRatio, SincResampler::kDefaultRequestSize,
174 &mock_source);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000175
176 // Retrieve benchmark iterations from command line.
andrew@webrtc.org076fc122013-02-15 03:54:22 +0000177 // TODO(ajm): Reintroduce this as a command line option.
178 const int kConvolveIterations = 1000000;
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000179
andrew@webrtc.org076fc122013-02-15 03:54:22 +0000180 printf("Benchmarking %d iterations:\n", kConvolveIterations);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000181
182 // Benchmark Convolve_C().
Niels Möllerd28db7f2016-05-10 16:31:47 +0200183 int64_t start = rtc::TimeNanos();
andrew@webrtc.org076fc122013-02-15 03:54:22 +0000184 for (int i = 0; i < kConvolveIterations; ++i) {
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000185 resampler.Convolve_C(
186 resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
187 resampler.kernel_storage_.get(), kKernelInterpolationFactor);
188 }
Niels Möllerd28db7f2016-05-10 16:31:47 +0200189 double total_time_c_us =
190 (rtc::TimeNanos() - start) / rtc::kNumNanosecsPerMicrosec;
andrew@webrtc.org076fc122013-02-15 03:54:22 +0000191 printf("Convolve_C took %.2fms.\n", total_time_c_us / 1000);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000192
193#if defined(CONVOLVE_FUNC)
andrew@webrtc.orgc6a37552013-05-08 20:35:43 +0000194#if defined(WEBRTC_ARCH_X86_FAMILY)
195 ASSERT_TRUE(WebRtc_GetCPUInfo(kSSE2));
196#elif defined(WEBRTC_ARCH_ARM_V7)
197 ASSERT_TRUE(WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON);
198#endif
199
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000200 // Benchmark with unaligned input pointer.
Niels Möllerd28db7f2016-05-10 16:31:47 +0200201 start = rtc::TimeNanos();
andrew@webrtc.org076fc122013-02-15 03:54:22 +0000202 for (int j = 0; j < kConvolveIterations; ++j) {
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000203 resampler.CONVOLVE_FUNC(
204 resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(),
205 resampler.kernel_storage_.get(), kKernelInterpolationFactor);
206 }
andrew@webrtc.org076fc122013-02-15 03:54:22 +0000207 double total_time_optimized_unaligned_us =
Niels Möllerd28db7f2016-05-10 16:31:47 +0200208 (rtc::TimeNanos() - start) / rtc::kNumNanosecsPerMicrosec;
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000209 printf(STRINGIZE(CONVOLVE_FUNC) "(unaligned) took %.2fms; which is %.2fx "
andrew@webrtc.org076fc122013-02-15 03:54:22 +0000210 "faster than Convolve_C.\n", total_time_optimized_unaligned_us / 1000,
211 total_time_c_us / total_time_optimized_unaligned_us);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000212
213 // Benchmark with aligned input pointer.
Niels Möllerd28db7f2016-05-10 16:31:47 +0200214 start = rtc::TimeNanos();
andrew@webrtc.org076fc122013-02-15 03:54:22 +0000215 for (int j = 0; j < kConvolveIterations; ++j) {
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000216 resampler.CONVOLVE_FUNC(
217 resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
218 resampler.kernel_storage_.get(), kKernelInterpolationFactor);
219 }
andrew@webrtc.org076fc122013-02-15 03:54:22 +0000220 double total_time_optimized_aligned_us =
Niels Möllerd28db7f2016-05-10 16:31:47 +0200221 (rtc::TimeNanos() - start) / rtc::kNumNanosecsPerMicrosec;
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000222 printf(STRINGIZE(CONVOLVE_FUNC) " (aligned) took %.2fms; which is %.2fx "
223 "faster than Convolve_C and %.2fx faster than "
224 STRINGIZE(CONVOLVE_FUNC) " (unaligned).\n",
andrew@webrtc.org076fc122013-02-15 03:54:22 +0000225 total_time_optimized_aligned_us / 1000,
226 total_time_c_us / total_time_optimized_aligned_us,
227 total_time_optimized_unaligned_us / total_time_optimized_aligned_us);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000228#endif
229}
230
231#undef CONVOLVE_FUNC
232
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000233typedef std::tr1::tuple<int, int, double, double> SincResamplerTestData;
234class SincResamplerTest
235 : public testing::TestWithParam<SincResamplerTestData> {
236 public:
237 SincResamplerTest()
238 : input_rate_(std::tr1::get<0>(GetParam())),
239 output_rate_(std::tr1::get<1>(GetParam())),
240 rms_error_(std::tr1::get<2>(GetParam())),
241 low_freq_error_(std::tr1::get<3>(GetParam())) {
242 }
243
244 virtual ~SincResamplerTest() {}
245
246 protected:
247 int input_rate_;
248 int output_rate_;
249 double rms_error_;
250 double low_freq_error_;
251};
252
253// Tests resampling using a given input and output sample rate.
254TEST_P(SincResamplerTest, Resample) {
255 // Make comparisons using one second of data.
256 static const double kTestDurationSecs = 1;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700257 const size_t input_samples =
258 static_cast<size_t>(kTestDurationSecs * input_rate_);
259 const size_t output_samples =
260 static_cast<size_t>(kTestDurationSecs * output_rate_);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000261
262 // Nyquist frequency for the input sampling rate.
andrew@webrtc.org8fc05fe2013-04-26 14:56:51 +0000263 const double input_nyquist_freq = 0.5 * input_rate_;
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000264
265 // Source for data to be resampled.
266 SinusoidalLinearChirpSource resampler_source(
andrew@webrtc.org8fc05fe2013-04-26 14:56:51 +0000267 input_rate_, input_samples, input_nyquist_freq, 0);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000268
andrew@webrtc.orgc6a37552013-05-08 20:35:43 +0000269 const double io_ratio = input_rate_ / static_cast<double>(output_rate_);
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +0000270 SincResampler resampler(io_ratio, SincResampler::kDefaultRequestSize,
271 &resampler_source);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000272
andrew@webrtc.orgc6a37552013-05-08 20:35:43 +0000273 // Force an update to the sample rate ratio to ensure dyanmic sample rate
274 // changes are working correctly.
kwibergc2b785d2016-02-24 05:22:32 -0800275 std::unique_ptr<float[]> kernel(new float[SincResampler::kKernelStorageSize]);
andrew@webrtc.orgc6a37552013-05-08 20:35:43 +0000276 memcpy(kernel.get(), resampler.get_kernel_for_testing(),
277 SincResampler::kKernelStorageSize);
278 resampler.SetRatio(M_PI);
279 ASSERT_NE(0, memcmp(kernel.get(), resampler.get_kernel_for_testing(),
280 SincResampler::kKernelStorageSize));
281 resampler.SetRatio(io_ratio);
282 ASSERT_EQ(0, memcmp(kernel.get(), resampler.get_kernel_for_testing(),
283 SincResampler::kKernelStorageSize));
284
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000285 // TODO(dalecurtis): If we switch to AVX/SSE optimization, we'll need to
286 // allocate these on 32-byte boundaries and ensure they're sized % 32 bytes.
kwibergc2b785d2016-02-24 05:22:32 -0800287 std::unique_ptr<float[]> resampled_destination(new float[output_samples]);
288 std::unique_ptr<float[]> pure_destination(new float[output_samples]);
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000289
290 // Generate resampled signal.
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +0000291 resampler.Resample(output_samples, resampled_destination.get());
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000292
293 // Generate pure signal.
294 SinusoidalLinearChirpSource pure_source(
andrew@webrtc.org8fc05fe2013-04-26 14:56:51 +0000295 output_rate_, output_samples, input_nyquist_freq, 0);
andrew@webrtc.orgb86fbaf2013-07-25 22:04:30 +0000296 pure_source.Run(output_samples, pure_destination.get());
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000297
298 // Range of the Nyquist frequency (0.5 * min(input rate, output_rate)) which
299 // we refer to as low and high.
300 static const double kLowFrequencyNyquistRange = 0.7;
301 static const double kHighFrequencyNyquistRange = 0.9;
302
303 // Calculate Root-Mean-Square-Error and maximum error for the resampling.
304 double sum_of_squares = 0;
305 double low_freq_max_error = 0;
306 double high_freq_max_error = 0;
307 int minimum_rate = std::min(input_rate_, output_rate_);
308 double low_frequency_range = kLowFrequencyNyquistRange * 0.5 * minimum_rate;
309 double high_frequency_range = kHighFrequencyNyquistRange * 0.5 * minimum_rate;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700310 for (size_t i = 0; i < output_samples; ++i) {
andrew@webrtc.orga8ef8112013-02-13 23:00:49 +0000311 double error = fabs(resampled_destination[i] - pure_destination[i]);
312
313 if (pure_source.Frequency(i) < low_frequency_range) {
314 if (error > low_freq_max_error)
315 low_freq_max_error = error;
316 } else if (pure_source.Frequency(i) < high_frequency_range) {
317 if (error > high_freq_max_error)
318 high_freq_max_error = error;
319 }
320 // TODO(dalecurtis): Sanity check frequencies > kHighFrequencyNyquistRange.
321
322 sum_of_squares += error * error;
323 }
324
325 double rms_error = sqrt(sum_of_squares / output_samples);
326
327 // Convert each error to dbFS.
328 #define DBFS(x) 20 * log10(x)
329 rms_error = DBFS(rms_error);
330 low_freq_max_error = DBFS(low_freq_max_error);
331 high_freq_max_error = DBFS(high_freq_max_error);
332
333 EXPECT_LE(rms_error, rms_error_);
334 EXPECT_LE(low_freq_max_error, low_freq_error_);
335
336 // All conversions currently have a high frequency error around -6 dbFS.
337 static const double kHighFrequencyMaxError = -6.02;
338 EXPECT_LE(high_freq_max_error, kHighFrequencyMaxError);
339}
340
341// Almost all conversions have an RMS error of around -14 dbFS.
342static const double kResamplingRMSError = -14.58;
343
344// Thresholds chosen arbitrarily based on what each resampling reported during
345// testing. All thresholds are in dbFS, http://en.wikipedia.org/wiki/DBFS.
346INSTANTIATE_TEST_CASE_P(
347 SincResamplerTest, SincResamplerTest, testing::Values(
348 // To 44.1kHz
349 std::tr1::make_tuple(8000, 44100, kResamplingRMSError, -62.73),
350 std::tr1::make_tuple(11025, 44100, kResamplingRMSError, -72.19),
351 std::tr1::make_tuple(16000, 44100, kResamplingRMSError, -62.54),
352 std::tr1::make_tuple(22050, 44100, kResamplingRMSError, -73.53),
353 std::tr1::make_tuple(32000, 44100, kResamplingRMSError, -63.32),
354 std::tr1::make_tuple(44100, 44100, kResamplingRMSError, -73.53),
355 std::tr1::make_tuple(48000, 44100, -15.01, -64.04),
356 std::tr1::make_tuple(96000, 44100, -18.49, -25.51),
357 std::tr1::make_tuple(192000, 44100, -20.50, -13.31),
358
359 // To 48kHz
360 std::tr1::make_tuple(8000, 48000, kResamplingRMSError, -63.43),
361 std::tr1::make_tuple(11025, 48000, kResamplingRMSError, -62.61),
362 std::tr1::make_tuple(16000, 48000, kResamplingRMSError, -63.96),
363 std::tr1::make_tuple(22050, 48000, kResamplingRMSError, -62.42),
364 std::tr1::make_tuple(32000, 48000, kResamplingRMSError, -64.04),
365 std::tr1::make_tuple(44100, 48000, kResamplingRMSError, -62.63),
366 std::tr1::make_tuple(48000, 48000, kResamplingRMSError, -73.52),
367 std::tr1::make_tuple(96000, 48000, -18.40, -28.44),
368 std::tr1::make_tuple(192000, 48000, -20.43, -14.11),
369
370 // To 96kHz
371 std::tr1::make_tuple(8000, 96000, kResamplingRMSError, -63.19),
372 std::tr1::make_tuple(11025, 96000, kResamplingRMSError, -62.61),
373 std::tr1::make_tuple(16000, 96000, kResamplingRMSError, -63.39),
374 std::tr1::make_tuple(22050, 96000, kResamplingRMSError, -62.42),
375 std::tr1::make_tuple(32000, 96000, kResamplingRMSError, -63.95),
376 std::tr1::make_tuple(44100, 96000, kResamplingRMSError, -62.63),
377 std::tr1::make_tuple(48000, 96000, kResamplingRMSError, -73.52),
378 std::tr1::make_tuple(96000, 96000, kResamplingRMSError, -73.52),
379 std::tr1::make_tuple(192000, 96000, kResamplingRMSError, -28.41),
380
381 // To 192kHz
382 std::tr1::make_tuple(8000, 192000, kResamplingRMSError, -63.10),
383 std::tr1::make_tuple(11025, 192000, kResamplingRMSError, -62.61),
384 std::tr1::make_tuple(16000, 192000, kResamplingRMSError, -63.14),
385 std::tr1::make_tuple(22050, 192000, kResamplingRMSError, -62.42),
386 std::tr1::make_tuple(32000, 192000, kResamplingRMSError, -63.38),
387 std::tr1::make_tuple(44100, 192000, kResamplingRMSError, -62.63),
388 std::tr1::make_tuple(48000, 192000, kResamplingRMSError, -73.44),
389 std::tr1::make_tuple(96000, 192000, kResamplingRMSError, -73.52),
390 std::tr1::make_tuple(192000, 192000, kResamplingRMSError, -73.52)));
391
andrew@webrtc.org076fc122013-02-15 03:54:22 +0000392} // namespace webrtc