summaryrefslogtreecommitdiffstats
path: root/media/base/sinc_resampler.h
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-11 21:58:08 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-11 21:58:08 +0000
commita5e97e2b8623e66712abca17945f940c0f2c6591 (patch)
tree9c04e04c599afcd9427fc7d6bf0dbc24b100a884 /media/base/sinc_resampler.h
parent47b11873a6a9ac3a59c3f22a5410317048266fff (diff)
downloadchromium_src-a5e97e2b8623e66712abca17945f940c0f2c6591.zip
chromium_src-a5e97e2b8623e66712abca17945f940c0f2c6591.tar.gz
chromium_src-a5e97e2b8623e66712abca17945f940c0f2c6591.tar.bz2
Add SincResampler ported from WebKit.
This is a partial port of WebAudio's SincResampler from WebKit formatted and culled for use by Chrome Media. We can't directly use the one in WebKit as it's layed under a ton of abstraction and is tightly coupled with WebKit objects. Test generates a swept sine wave and calculates the RMS error for common sample rates (via UMA stats). MultiChannelResampler and AudioRenderMixer changes to support resampling will come in later CLs. The 1000 ft view is that MultiChannelResampler will implement SincResampler:: AudioSourceProvider and AudioRendererMixer will implement a new MultiChannelResampler::MultiChannelAudioSourceProvider interface. When resampling is necessary AudioRenderMixer will feed itself into a MultiChannelResampler instance which will poll data as necessary and feed it channel by channel into a set of SincResamplers (one for each channel). We want to resample post-mixing since resampling is a much more expensive operation. Original for reference: http://git.chromium.org/gitweb/?p=external/Webkit.git&a=blob&f=Source/WebCore/platform/audio/SincResampler.cpp Visual plot of 44100 to 48000 for reference; red line is the resampled signal and the green line is the reference signal. Ideally only the pure signal (green) should be seen. Any bit of the resampled signal showing (red) is where the resampling algorithm is incorrect: http://i.imgur.com/1vsaI.png BUG=133637 TEST=New unittests. Review URL: https://chromiumcodereview.appspot.com/10702050 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146219 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base/sinc_resampler.h')
-rw-r--r--media/base/sinc_resampler.h71
1 files changed, 71 insertions, 0 deletions
diff --git a/media/base/sinc_resampler.h b/media/base/sinc_resampler.h
new file mode 100644
index 0000000..58f5c2d
--- /dev/null
+++ b/media/base/sinc_resampler.h
@@ -0,0 +1,71 @@
+// 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.
+
+#ifndef MEDIA_BASE_SINC_RESAMPLER_H_
+#define MEDIA_BASE_SINC_RESAMPLER_H_
+
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "media/base/media_export.h"
+
+namespace media {
+
+// SincResampler is a high-quality single-channel sample-rate converter.
+class MEDIA_EXPORT SincResampler {
+ public:
+ // Callback type for providing more data into the resampler. Expects |frames|
+ // of data to be rendered into |destination|; zero padded if not enough frames
+ // are available to satisfy the request.
+ typedef base::Callback<void(float* destination, int frames)> ReadCB;
+
+ // Constructs a SincResampler with the specified |read_cb|, which is used to
+ // acquire audio data for resampling. |io_sample_rate_ratio| is the ratio of
+ // input / output sample rates.
+ SincResampler(double io_sample_rate_ratio, const ReadCB& read_cb);
+ virtual ~SincResampler();
+
+ // Resample |frames| of data from |read_cb_| into |destination|.
+ void Resample(float* destination, int frames);
+
+ // The maximum size in frames that guarantees Resample() will only make a
+ // single call to |read_cb_| for more data.
+ int ChunkSize();
+
+ private:
+ void InitializeKernel();
+
+ // The ratio of input / output sample rates.
+ double io_sample_rate_ratio_;
+
+ // An index on the source input buffer with sub-sample precision. It must be
+ // double precision to avoid drift.
+ double virtual_source_idx_;
+
+ // The buffer is primed once at the very beginning of processing.
+ bool buffer_primed_;
+
+ // Source of data for resampling.
+ ReadCB read_cb_;
+
+ // Contains kKernelOffsetCount kernels back-to-back, each of size kKernelSize.
+ // The kernel offsets are sub-sample shifts of a windowed sinc shifted from
+ // 0.0 to 1.0 sample.
+ scoped_array<float> kernel_storage_;
+
+ // Data from the source is copied into this buffer for each processing pass.
+ scoped_array<float> input_buffer_;
+
+ // Pointers to the various regions inside |input_buffer_|. See the diagram at
+ // the top of the .cc file for more information.
+ float* const r0_;
+ float* const r1_;
+ float* const r2_;
+ float* const r3_;
+ float* const r4_;
+ float* const r5_;
+};
+
+} // namespace media
+
+#endif // MEDIA_BASE_SINC_RESAMPLER_H_