From cf491a925e221122f81873bd041c5c136027e385 Mon Sep 17 00:00:00 2001 From: Ganesh Ajjanagadde Date: Mon, 9 Nov 2015 00:38:45 -0500 Subject: swresample/resample: speed up Blackman Nuttall filter This may be a slightly surprising optimization, but is actually based on an understanding of how math libraries compute trigonometric functions. Explanation is given here so that future development uses libm more effectively across the codebase. All libm's essentially compute transcendental functions via some kind of polynomial approximation, be it Taylor-Maclaurin or Chebyshev. Correction terms are added via polynomial correction factors when needed to squeeze out the last bits of accuracy. Lookup tables are also inserted strategically. In the case of trigonometric functions, periodicity is exploited via first doing a range reduction to an interval around zero, and then using some polynomial approximation. This range reduction is the most natural way of doing things - else one would need polynomials for ranges in different periods which makes no sense whatsoever. To avoid the need for the range reduction, it is helpful to feed in arguments as close to the origin as possible for the trigonometric functions. In fact, this also makes sense from an accuracy point of view: IEEE floating point has far more resolution for small numbers than big ones. This patch does this for the Blackman-Nuttall filter, and yields a non-negligible speedup. Sample benchmark (x86-64, Haswell, GNU/Linux) test: fate-swr-resample-dblp-2626-44100 old: 18893514 decicycles in build_filter (loop 1000), 256 runs, 0 skips 18599863 decicycles in build_filter (loop 1000), 512 runs, 0 skips 18445574 decicycles in build_filter (loop 1000), 1000 runs, 24 skips new: 16290697 decicycles in build_filter (loop 1000), 256 runs, 0 skips 16267172 decicycles in build_filter (loop 1000), 512 runs, 0 skips 16251105 decicycles in build_filter (loop 1000), 1000 runs, 24 skips Reviewed-by: Michael Niedermayer Signed-off-by: Ganesh Ajjanagadde --- libswresample/resample.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libswresample/resample.c') diff --git a/libswresample/resample.c b/libswresample/resample.c index d0a406e5e4..c5ee62d842 100644 --- a/libswresample/resample.c +++ b/libswresample/resample.c @@ -180,8 +180,8 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap else y= d*(-4 + 8*x - 5*x*x + x*x*x); break;} case SWR_FILTER_TYPE_BLACKMAN_NUTTALL: - w = 2.0*x / (factor*tap_count) + M_PI; - t = cos(w); + w = 2.0*x / (factor*tap_count); + t = -cos(w); y *= 0.3635819 - 0.4891775 * t + 0.1365995 * (2*t*t-1) - 0.0106411 * (4*t*t*t - 3*t); break; case SWR_FILTER_TYPE_KAISER: -- cgit v1.2.3