README revision 7c478bd95313f5f23a4c958a745db2134aa03244
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License"). You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
/*
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
Bandlimited Interpolation
In bandlimited interpolation a windowed sinc function is used to
interpolate input samples and implement sample rate conversion.
More information on the algorithm can be found on the website at
http://ccrma-www.stanford.edu/~jos/resample. Choices to be made
during an implementation include (i) the type of window with which
to truncate the infinitely long sinc function (ii) the length of
the latter window (i.e. how many sinc zero-crossings to include)
(iii) the density of sinc function sampling (iv) the number of bits
used to encode each sinc coefficient (v) whether to interpolate
sinc coefficients during sample rate conversion.
In our implementation we (i) use a Kaiser window to truncate
the sinc function (ii) sample up to the 10th zero crossing (iii)
sample the interval between each zero crossing 256 times (iv)
use an integer (32 bits) to encode each coefficient (v) do not,
for performance reasons, perform coefficient interpolation during
conversion.
Using the above settings we end up with a conversion table which
contains (2 * 10 + 1) * 256 = 5376 entries. (We add some more to
simplify the implementation.) For performance reasons, we use two
copies of the table, one for up and one for downsampling. Each is
a reordering of the other. We also use separate functions for up
and downsampling mono and stereo files giving 4 resampling functions.
Each can handle, theoretically, any start/target sample rate
configuration and is accurate to 1Hz.
Upsampling
During conversion the sinc window is centered over the current output
sample location. We project upwards from input sample values under
the sinc "umbrella" and multiply and sum corresponding input samples
and sinc coefficients. The sinc function acts like a low pass filter
with a cut off frequency of Fs/2 where Fs is the input sample rate.
The number of multiply-adds is fixed, irrespective of the start and
target sample rates. Often an input sample location will not intersect
with a prestored coefficient value and as stated earlier we do not
interpolate but multiply by the nearest coefficient value.
Downsampling
Downsampling is not as straightforward as upsampling. The stored
sinc table must be traversed in such a way as to act like a low
pass filter but this time with a cut off frequency equal to Fs'/2
where Fs' is the target sample rate. To achieve this the sinc
coefficients are stretched over a longer interval of the input
signal (compared to upsampling) and traversed at a slower rate.
Compared to upsampling there are then more multiply-adds to be
performed but this is offset by the fact that there are fewer
output samples to be generated.
Notes
When resampling we are performing an interpolation. This interpolation
is imperfect and errors will occur. Furthermore, in our implementation
there is often no direct mapping from filter coefficents to input
samples and in this case we use the closest filter coefficient which
introduces more error. These errors lead to unwanted frequencies in
the audio output signal. Many of these could be removed or reduced by
(i) employing a greater sampling density over the stored sinc function,
thereby increasing the overall table size and lowering the error
introduced by a lack of filter coefficient interpolation or (ii)
maintaining the same overall table size but interpolating between
filter coefficients for increased accuracy at a computational cost.
Implementing either of these would have a significant effect on
output audio quality.
As is stands our current implementation should theoretically exhibit a
stopband rejection of 60dB and a transition bandwidth of ~34% (these
are theoretical values since the errors mentioned above drag quality
downwards). Our transition band is centered over Fs/2 with the result
that should there be significant energy in the upper ~17% of the spectrum
there will be a considerable artifact introduced in the output signal.
We take that chance. Stopband rejection can be increased at the expense
of transition bandwidth and transition bandwidth can be lessened by
using more sinc zero crossings (i.e. lengthening the filter kernel).