summaryrefslogtreecommitdiff
path: root/libswresample/resample.c
diff options
context:
space:
mode:
Diffstat (limited to 'libswresample/resample.c')
-rw-r--r--libswresample/resample.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/libswresample/resample.c b/libswresample/resample.c
index 072e0d6a78..d0a406e5e4 100644
--- a/libswresample/resample.c
+++ b/libswresample/resample.c
@@ -144,24 +144,34 @@ static double bessel(double x) {
static int build_filter(ResampleContext *c, void *filter, double factor, int tap_count, int alloc, int phase_count, int scale,
int filter_type, double kaiser_beta){
int ph, i;
- double x, y, w, t;
+ double x, y, w, t, s;
double *tab = av_malloc_array(tap_count+1, sizeof(*tab));
+ double *sin_lut = av_malloc_array(phase_count / 2 + 1, sizeof(*sin_lut));
const int center= (tap_count-1)/2;
- if (!tab)
- return AVERROR(ENOMEM);
+ if (!tab || !sin_lut)
+ goto fail;
/* if upsampling, only need to interpolate, no filter */
if (factor > 1.0)
factor = 1.0;
av_assert0(phase_count == 1 || phase_count % 2 == 0);
+
+ if (factor == 1.0) {
+ for (ph = 0; ph <= phase_count / 2; ph++)
+ sin_lut[ph] = sin(M_PI * ph / phase_count);
+ }
for(ph = 0; ph <= phase_count / 2; ph++) {
double norm = 0;
+ s = sin_lut[ph];
for(i=0;i<=tap_count;i++) {
x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
if (x == 0) y = 1.0;
- else y = sin(x) / x;
+ else if (factor == 1.0)
+ y = s / x;
+ else
+ y = sin(x) / x;
switch(filter_type){
case SWR_FILTER_TYPE_CUBIC:{
const float d= -0.5; //first order derivative = -0.5
@@ -183,6 +193,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap
}
tab[i] = y;
+ s = -s;
if (i < tap_count)
norm += y;
}
@@ -278,7 +289,9 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap
}
#endif
+fail:
av_free(tab);
+ av_free(sin_lut);
return 0;
}