From bde8ec9bf7f84427f403755282b45d3994fad7ce Mon Sep 17 00:00:00 2001 From: David Schleef Date: Tue, 23 Aug 2005 19:29:38 +0000 Subject: gst/audioresample/Makefile.am: Leet audioresampling code Original commit message from CVS: * gst/audioresample/Makefile.am: Leet audioresampling code * gst/audioresample/buffer.c: * gst/audioresample/buffer.h: * gst/audioresample/debug.c: * gst/audioresample/debug.h: * gst/audioresample/functable.c: * gst/audioresample/functable.h: * gst/audioresample/gstaudioresample.c: * gst/audioresample/gstaudioresample.h: * gst/audioresample/resample.c: * gst/audioresample/resample.h: * gst/audioresample/resample_chunk.c: * gst/audioresample/resample_functable.c: * gst/audioresample/resample_ref.c: --- gst/audioresample/functable.c | 254 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 gst/audioresample/functable.c (limited to 'gst/audioresample/functable.c') diff --git a/gst/audioresample/functable.c b/gst/audioresample/functable.c new file mode 100644 index 00000000..41844015 --- /dev/null +++ b/gst/audioresample/functable.c @@ -0,0 +1,254 @@ +/* Resampling library + * Copyright (C) <2001> David A. Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include +#include + + + +void +functable_func_sinc (double *fx, double *dfx, double x, void *closure) +{ + if (x == 0) { + *fx = 1; + *dfx = 0; + return; + } + + *fx = sin (x) / x; + *dfx = (cos (x) - sin (x) / x) / x; +} + +void +functable_func_boxcar (double *fx, double *dfx, double x, void *closure) +{ + double width = *(double *) closure; + + if (x < width && x > -width) { + *fx = 1; + } else { + *fx = 0; + } + *dfx = 0; +} + +void +functable_func_hanning (double *fx, double *dfx, double x, void *closure) +{ + double width = *(double *) closure; + + if (x < width && x > -width) { + x /= width; + *fx = (1 - x * x) * (1 - x * x); + *dfx = -2 * 2 * x / width * (1 - x * x); + } else { + *fx = 0; + *dfx = 0; + } +} + + +Functable * +functable_new (void) +{ + Functable *ft; + + ft = malloc (sizeof (Functable)); + memset (ft, 0, sizeof (Functable)); + + return ft; +} + +void +functable_free (Functable * ft) +{ + free (ft); +} + +void +functable_set_length (Functable * t, int length) +{ + t->length = length; +} + +void +functable_set_offset (Functable * t, double offset) +{ + t->offset = offset; +} + +void +functable_set_multiplier (Functable * t, double multiplier) +{ + t->multiplier = multiplier; +} + +void +functable_calculate (Functable * t, FunctableFunc func, void *closure) +{ + int i; + double x; + + if (t->fx) + free (t->fx); + if (t->dfx) + free (t->dfx); + + t->fx = malloc (sizeof (double) * (t->length + 1)); + t->dfx = malloc (sizeof (double) * (t->length + 1)); + + t->inv_multiplier = 1.0 / t->multiplier; + + for (i = 0; i < t->length + 1; i++) { + x = t->offset + t->multiplier * i; + + func (&t->fx[i], &t->dfx[i], x, closure); + } +} + +void +functable_calculate_multiply (Functable * t, FunctableFunc func, void *closure) +{ + int i; + double x; + + for (i = 0; i < t->length + 1; i++) { + double afx, adfx, bfx, bdfx; + + afx = t->fx[i]; + adfx = t->dfx[i]; + x = t->offset + t->multiplier * i; + func (&bfx, &bdfx, x, closure); + t->fx[i] = afx * bfx; + t->dfx[i] = afx * bdfx + adfx * bfx; + } + +} + +double +functable_evaluate (Functable * t, double x) +{ + int i; + double f0, f1, w0, w1; + double x2, x3; + double w; + + if (x < t->offset || x > (t->offset + t->length * t->multiplier)) { + RESAMPLE_DEBUG ("x out of range %g", x); + } + + x -= t->offset; + x *= t->inv_multiplier; + i = floor (x); + x -= i; + + x2 = x * x; + x3 = x2 * x; + + f1 = 3 * x2 - 2 * x3; + f0 = 1 - f1; + w0 = (x - 2 * x2 + x3) * t->multiplier; + w1 = (-x2 + x3) * t->multiplier; + + w = t->fx[i] * f0 + t->fx[i + 1] * f1 + t->dfx[i] * w0 + t->dfx[i + 1] * w1; + + /*w = t->fx[i] * (1-x) + t->fx[i+1] * x; */ + + return w; +} + + +double +functable_fir (Functable * t, double x, int n, double *data, int len) +{ + int i, j; + double f0, f1, w0, w1; + double x2, x3; + double w; + double sum; + + x -= t->offset; + x /= t->multiplier; + i = floor (x); + x -= i; + + x2 = x * x; + x3 = x2 * x; + + f1 = 3 * x2 - 2 * x3; + f0 = 1 - f1; + w0 = (x - 2 * x2 + x3) * t->multiplier; + w1 = (-x2 + x3) * t->multiplier; + + sum = 0; + for (j = 0; j < len; j++) { + w = t->fx[i] * f0 + t->fx[i + 1] * f1 + t->dfx[i] * w0 + t->dfx[i + 1] * w1; + sum += data[j * 2] * w; + i += n; + } + + return sum; +} + +void +functable_fir2 (Functable * t, double *r0, double *r1, double x, + int n, double *data, int len) +{ + int i, j; + double f0, f1, w0, w1; + double x2, x3; + double w; + double sum0, sum1; + double floor_x; + + x -= t->offset; + x *= t->inv_multiplier; + floor_x = floor (x); + i = floor_x; + x -= floor_x; + + x2 = x * x; + x3 = x2 * x; + + f1 = 3 * x2 - 2 * x3; + f0 = 1 - f1; + w0 = (x - 2 * x2 + x3) * t->multiplier; + w1 = (-x2 + x3) * t->multiplier; + + sum0 = 0; + sum1 = 0; + for (j = 0; j < len; j++) { + w = t->fx[i] * f0 + t->fx[i + 1] * f1 + t->dfx[i] * w0 + t->dfx[i + 1] * w1; + sum0 += data[j * 2] * w; + sum1 += data[j * 2 + 1] * w; + i += n; + } + + *r0 = sum0; + *r1 = sum1; +} -- cgit v1.2.1