mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-08 13:18:52 +00:00
|
||
---|---|---|
.. | ||
dtof.c | ||
dtos.c | ||
functable.c | ||
Makefile.am | ||
private.h | ||
README | ||
resample.c | ||
resample.h | ||
resample.vcproj | ||
test.c |
This is a snapshot of my current work developing an audio resampling library. While working on this library, I started writing lots of general purpose functions that should really be part of a larger library. Rather than have a constantly changing library, and since the current code is capable, I decided to freeze this codebase for use with gstreamer, and move active development of the code elsewhere. The algorithm used is based on Shannon's theorem, which says that you can recreate an input signal from equidistant samples using a sin(x)/x filter; thus, you can create new samples from the regenerated input signal. Since sin(x)/x is expensive to evaluate, an interpolated lookup table is used. Also, a windowing function (1-x^2)^2 is used, which aids the convergence of sin(x)/x for lower frequencies at the expense of higher. There is one tunable parameter, which is the filter length. Longer filter lengths are obviously slower, but more accurate. There's not much reason to use a filter length longer than 64, since other approximations start to dominate. Filter lengths as short as 8 are audially acceptable, but should not be considered for serious work. Performance: A PowerPC G4 at 400 Mhz can resample 2 audio channels at almost 10x speed with a filter length of 64, without using Altivec extensions. (My goal was 10x speed, which I almost reached. Maybe later.) Limitations: Currently only supports streams in the form of interleaved signed 16-bit samples. The test.c program is a simple regression test. It creates a test input pattern (1 sec at 48 khz) that is a frequency ramp from 0 to 24000 hz, and then converts it to 44100 hz using a filter length of 64. It then compares the result to the same pattern generated at 44100 hz, and outputs the result to the file "out". A graph of the correct output should have field 2 and field 4 almost equal (plus/minus 1) up to about sample 40000 (which corresponds to 20 khz), and then field 2 should be close to 0 above that. Running the test program will print to stdout something like the following: time 0.112526 average error 10k=0.4105 22k=639.34 The average error is RMS error over the range [0-10khz] and [0-22khz], and is expressed in sample values, for an input amplitude of 16000. Note that RMS errors below 1.0 can't really be compared, but basically this shows that below 10 khz, the resampler is nearly perfect. Most of the error is concentrated above 20 khz. If the average error is significantly larger after modifying the code, it's probably not good. dave...