Mercurial > libavcodec.hg
annotate resample2.c @ 11060:daff45175333 libavcodec
Make the jump-table section-relative for x86_64 with PIC enabled.
This allows to get rid of the macho64 specific hack that moves them
to rodata (with worse cache behaviour) and avoids textrels which
e.g. Gentoo does not allow for x86_64 libraries.
author | reimar |
---|---|
date | Sat, 30 Jan 2010 19:26:47 +0000 |
parents | 002cd0505064 |
children | 5cc6cb5167d8 |
rev | line source |
---|---|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
1 /* |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
2 * audio resampling |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
3 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
4 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3347
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3347
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3347
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
9 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3347
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3347
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
15 * Lesser General Public License for more details. |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
16 * |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3347
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
20 */ |
2967 | 21 |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
22 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
7377
diff
changeset
|
23 * @file libavcodec/resample2.c |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
24 * audio resampling |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
25 * @author Michael Niedermayer <michaelni@gmx.at> |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
26 */ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
27 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
28 #include "avcodec.h" |
2114
7f88c429ad65
ugly missing lrintf workaround by ("Steven M. Schultz" <sms at 2bsd dot com>)
michael
parents:
2109
diff
changeset
|
29 #include "dsputil.h" |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
30 |
4697
8e460c6a85a7
make high precision mode accessible at compile time
michael
parents:
4696
diff
changeset
|
31 #ifndef CONFIG_RESAMPLE_HP |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
32 #define FILTER_SHIFT 15 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
33 |
2304
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
34 #define FELEM int16_t |
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
35 #define FELEM2 int32_t |
4702 | 36 #define FELEML int64_t |
2304
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
37 #define FELEM_MAX INT16_MAX |
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
38 #define FELEM_MIN INT16_MIN |
4700
e210bbc7dd19
select more sensible default windows (= attenuation beyond the dynamic range of your input is silly if it negatively affects other parameters)
michael
parents:
4699
diff
changeset
|
39 #define WINDOW_TYPE 9 |
4702 | 40 #elif !defined(CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE) |
4708
0ebf322d148e
change high precision mode to 30 bits again after making the code less overflow sensitive
michael
parents:
4707
diff
changeset
|
41 #define FILTER_SHIFT 30 |
2304
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
42 |
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
43 #define FELEM int32_t |
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
44 #define FELEM2 int64_t |
4702 | 45 #define FELEML int64_t |
2304
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
46 #define FELEM_MAX INT32_MAX |
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
47 #define FELEM_MIN INT32_MIN |
4700
e210bbc7dd19
select more sensible default windows (= attenuation beyond the dynamic range of your input is silly if it negatively affects other parameters)
michael
parents:
4699
diff
changeset
|
48 #define WINDOW_TYPE 12 |
4702 | 49 #else |
50 #define FILTER_SHIFT 0 | |
51 | |
4709
6768647cc0fd
replace long double in the audiophile kiddy mode with doubles, its faster (and more portable) and the audiophile placebo 120db stopband attenuation isnt affected
michael
parents:
4708
diff
changeset
|
52 #define FELEM double |
6768647cc0fd
replace long double in the audiophile kiddy mode with doubles, its faster (and more portable) and the audiophile placebo 120db stopband attenuation isnt affected
michael
parents:
4708
diff
changeset
|
53 #define FELEM2 double |
6768647cc0fd
replace long double in the audiophile kiddy mode with doubles, its faster (and more portable) and the audiophile placebo 120db stopband attenuation isnt affected
michael
parents:
4708
diff
changeset
|
54 #define FELEML double |
4702 | 55 #define WINDOW_TYPE 24 |
2304
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
56 #endif |
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
57 |
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
58 |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
59 typedef struct AVResampleContext{ |
9252
fff66291d84d
Move av_class to AVResampleContext instead of ReSampleContext.
benoit
parents:
8778
diff
changeset
|
60 const AVClass *av_class; |
2304
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
61 FELEM *filter_bank; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
62 int filter_length; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
63 int ideal_dst_incr; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
64 int dst_incr; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
65 int index; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
66 int frac; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
67 int src_incr; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
68 int compensation_distance; |
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
69 int phase_shift; |
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
70 int phase_mask; |
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
71 int linear; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
72 }AVResampleContext; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
73 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
74 /** |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
75 * 0th order modified bessel function of the first kind. |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
76 */ |
3347
82277c821113
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
3036
diff
changeset
|
77 static double bessel(double x){ |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
78 double v=1; |
10778
002cd0505064
Stop the approximation in bessel() once it does no longer improve.
michael
parents:
9252
diff
changeset
|
79 double lastv=0; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
80 double t=1; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
81 int i; |
2967 | 82 |
4701
5fa551fb7640
optimize bessel function instead of trusting gcc to do trivial optimizations (as gcc doesnt ...)
michael
parents:
4700
diff
changeset
|
83 x= x*x/4; |
10778
002cd0505064
Stop the approximation in bessel() once it does no longer improve.
michael
parents:
9252
diff
changeset
|
84 for(i=1; v != lastv; i++){ |
002cd0505064
Stop the approximation in bessel() once it does no longer improve.
michael
parents:
9252
diff
changeset
|
85 lastv=v; |
4701
5fa551fb7640
optimize bessel function instead of trusting gcc to do trivial optimizations (as gcc doesnt ...)
michael
parents:
4700
diff
changeset
|
86 t *= x/(i*i); |
5fa551fb7640
optimize bessel function instead of trusting gcc to do trivial optimizations (as gcc doesnt ...)
michael
parents:
4700
diff
changeset
|
87 v += t; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
88 } |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
89 return v; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
90 } |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
91 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
92 /** |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
93 * builds a polyphase filterbank. |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
94 * @param factor resampling factor |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
95 * @param scale wanted sum of coefficients for each filter |
4699
4040ca52670a
make kaiser windows with other beta than 16 available
michael
parents:
4697
diff
changeset
|
96 * @param type 0->cubic, 1->blackman nuttall windowed sinc, 2..16->kaiser windowed sinc beta=2..16 |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
97 */ |
2304
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
98 void av_build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){ |
4822 | 99 int ph, i; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
100 double x, y, w, tab[tap_count]; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
101 const int center= (tap_count-1)/2; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
102 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
103 /* if upsampling, only need to interpolate, no filter */ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
104 if (factor > 1.0) |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
105 factor = 1.0; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
106 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
107 for(ph=0;ph<phase_count;ph++) { |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
108 double norm = 0; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
109 for(i=0;i<tap_count;i++) { |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
110 x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
111 if (x == 0) y = 1.0; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
112 else y = sin(x) / x; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
113 switch(type){ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
114 case 0:{ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
115 const float d= -0.5; //first order derivative = -0.5 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
116 x = fabs(((double)(i - center) - (double)ph / phase_count) * factor); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
117 if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*( -x*x + x*x*x); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
118 else y= d*(-4 + 8*x - 5*x*x + x*x*x); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
119 break;} |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
120 case 1: |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
121 w = 2.0*x / (factor*tap_count) + M_PI; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
122 y *= 0.3635819 - 0.4891775 * cos(w) + 0.1365995 * cos(2*w) - 0.0106411 * cos(3*w); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
123 break; |
4699
4040ca52670a
make kaiser windows with other beta than 16 available
michael
parents:
4697
diff
changeset
|
124 default: |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
125 w = 2.0*x / (factor*tap_count*M_PI); |
4699
4040ca52670a
make kaiser windows with other beta than 16 available
michael
parents:
4697
diff
changeset
|
126 y *= bessel(type*sqrt(FFMAX(1-w*w, 0))); |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
127 break; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
128 } |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
129 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
130 tab[i] = y; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
131 norm += y; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
132 } |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
133 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
134 /* normalize so that an uniform color remains the same */ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
135 for(i=0;i<tap_count;i++) { |
4702 | 136 #ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE |
137 filter[ph * tap_count + i] = tab[i] / norm; | |
138 #else | |
139 filter[ph * tap_count + i] = av_clip(lrintf(tab[i] * scale / norm), FELEM_MIN, FELEM_MAX); | |
140 #endif | |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
141 } |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
142 } |
4695 | 143 #if 0 |
144 { | |
145 #define LEN 1024 | |
146 int j,k; | |
147 double sine[LEN + tap_count]; | |
148 double filtered[LEN]; | |
149 double maxff=-2, minff=2, maxsf=-2, minsf=2; | |
150 for(i=0; i<LEN; i++){ | |
151 double ss=0, sf=0, ff=0; | |
152 for(j=0; j<LEN+tap_count; j++) | |
153 sine[j]= cos(i*j*M_PI/LEN); | |
154 for(j=0; j<LEN; j++){ | |
155 double sum=0; | |
156 ph=0; | |
157 for(k=0; k<tap_count; k++) | |
158 sum += filter[ph * tap_count + k] * sine[k+j]; | |
159 filtered[j]= sum / (1<<FILTER_SHIFT); | |
160 ss+= sine[j + center] * sine[j + center]; | |
161 ff+= filtered[j] * filtered[j]; | |
162 sf+= sine[j + center] * filtered[j]; | |
163 } | |
164 ss= sqrt(2*ss/LEN); | |
165 ff= sqrt(2*ff/LEN); | |
166 sf= 2*sf/LEN; | |
167 maxff= FFMAX(maxff, ff); | |
168 minff= FFMIN(minff, ff); | |
169 maxsf= FFMAX(maxsf, sf); | |
170 minsf= FFMIN(minsf, sf); | |
171 if(i%11==0){ | |
4702 | 172 av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf); |
4695 | 173 minff=minsf= 2; |
174 maxff=maxsf= -2; | |
175 } | |
176 } | |
177 } | |
178 #endif | |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
179 } |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
180 |
2308 | 181 AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff){ |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
182 AVResampleContext *c= av_mallocz(sizeof(AVResampleContext)); |
2308 | 183 double factor= FFMIN(out_rate * cutoff / in_rate, 1.0); |
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
184 int phase_count= 1<<phase_shift; |
2967 | 185 |
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
186 c->phase_shift= phase_shift; |
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
187 c->phase_mask= phase_count-1; |
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
188 c->linear= linear; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
189 |
2835
d4c4b84e0fac
minor fixes for invalid audio data patch by (Wolfram Gloger: wmglo, dent med uni-muenchen de)
michael
parents:
2426
diff
changeset
|
190 c->filter_length= FFMAX((int)ceil(filter_size/factor), 1); |
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
191 c->filter_bank= av_mallocz(c->filter_length*(phase_count+1)*sizeof(FELEM)); |
4700
e210bbc7dd19
select more sensible default windows (= attenuation beyond the dynamic range of your input is silly if it negatively affects other parameters)
michael
parents:
4699
diff
changeset
|
192 av_build_filter(c->filter_bank, factor, c->filter_length, phase_count, 1<<FILTER_SHIFT, WINDOW_TYPE); |
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
193 memcpy(&c->filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM)); |
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
194 c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1]; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
195 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
196 c->src_incr= out_rate; |
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
197 c->ideal_dst_incr= c->dst_incr= in_rate * phase_count; |
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
198 c->index= -phase_count*((c->filter_length-1)/2); |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
199 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
200 return c; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
201 } |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
202 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
203 void av_resample_close(AVResampleContext *c){ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
204 av_freep(&c->filter_bank); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
205 av_freep(&c); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
206 } |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
207 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
208 void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){ |
2083 | 209 // sample_delta += (c->ideal_dst_incr - c->dst_incr)*(int64_t)c->compensation_distance / c->ideal_dst_incr; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
210 c->compensation_distance= compensation_distance; |
2083 | 211 c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
212 } |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
213 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
214 int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx){ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
215 int dst_index, i; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
216 int index= c->index; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
217 int frac= c->frac; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
218 int dst_incr_frac= c->dst_incr % c->src_incr; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
219 int dst_incr= c->dst_incr / c->src_incr; |
2277 | 220 int compensation_distance= c->compensation_distance; |
2405
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
221 |
2403 | 222 if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){ |
2405
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
223 int64_t index2= ((int64_t)index)<<32; |
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
224 int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr; |
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
225 dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr); |
2967 | 226 |
2403 | 227 for(dst_index=0; dst_index < dst_size; dst_index++){ |
2405
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
228 dst[dst_index] = src[index2>>32]; |
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
229 index2 += incr; |
2403 | 230 } |
2405
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
231 frac += dst_index * dst_incr_frac; |
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
232 index += dst_index * dst_incr; |
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
233 index += frac / c->src_incr; |
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
234 frac %= c->src_incr; |
2403 | 235 }else{ |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
236 for(dst_index=0; dst_index < dst_size; dst_index++){ |
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
237 FELEM *filter= c->filter_bank + c->filter_length*(index & c->phase_mask); |
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
238 int sample_index= index >> c->phase_shift; |
2304
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
239 FELEM2 val=0; |
2967 | 240 |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
241 if(sample_index < 0){ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
242 for(i=0; i<c->filter_length; i++) |
4001 | 243 val += src[FFABS(sample_index + i) % src_size] * filter[i]; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
244 }else if(sample_index + c->filter_length > src_size){ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
245 break; |
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
246 }else if(c->linear){ |
4707
441cded6920c
optimize linear filter coeff interpolation code, this also makes the code less prone to overflows
michael
parents:
4703
diff
changeset
|
247 FELEM2 v2=0; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
248 for(i=0; i<c->filter_length; i++){ |
4707
441cded6920c
optimize linear filter coeff interpolation code, this also makes the code less prone to overflows
michael
parents:
4703
diff
changeset
|
249 val += src[sample_index + i] * (FELEM2)filter[i]; |
441cded6920c
optimize linear filter coeff interpolation code, this also makes the code less prone to overflows
michael
parents:
4703
diff
changeset
|
250 v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_length]; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
251 } |
4707
441cded6920c
optimize linear filter coeff interpolation code, this also makes the code less prone to overflows
michael
parents:
4703
diff
changeset
|
252 val+=(v2-val)*(FELEML)frac / c->src_incr; |
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
253 }else{ |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
254 for(i=0; i<c->filter_length; i++){ |
2304
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
255 val += src[sample_index + i] * (FELEM2)filter[i]; |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
256 } |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
257 } |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
258 |
4702 | 259 #ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE |
5523 | 260 dst[dst_index] = av_clip_int16(lrintf(val)); |
4702 | 261 #else |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
262 val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
263 dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val; |
4702 | 264 #endif |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
265 |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
266 frac += dst_incr_frac; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
267 index += dst_incr; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
268 if(frac >= c->src_incr){ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
269 frac -= c->src_incr; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
270 index++; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
271 } |
2277 | 272 |
273 if(dst_index + 1 == compensation_distance){ | |
274 compensation_distance= 0; | |
275 dst_incr_frac= c->ideal_dst_incr % c->src_incr; | |
276 dst_incr= c->ideal_dst_incr / c->src_incr; | |
277 } | |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
278 } |
2403 | 279 } |
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
280 *consumed= FFMAX(index, 0) >> c->phase_shift; |
2307
df3e4a8e6aac
100l (dont reset the sample position at the block end)
michael
parents:
2306
diff
changeset
|
281 if(index>=0) index &= c->phase_mask; |
2109 | 282 |
2277 | 283 if(compensation_distance){ |
284 compensation_distance -= dst_index; | |
285 assert(compensation_distance > 0); | |
286 } | |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
287 if(update_ctx){ |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
288 c->frac= frac; |
2109 | 289 c->index= index; |
2277 | 290 c->dst_incr= dst_incr_frac + c->src_incr*dst_incr; |
291 c->compensation_distance= compensation_distance; | |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
292 } |
2967 | 293 #if 0 |
2083 | 294 if(update_ctx && !c->compensation_distance){ |
295 #undef rand | |
296 av_resample_compensate(c, rand() % (8000*2) - 8000, 8000*2); | |
297 av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", c->dst_incr, c->ideal_dst_incr, c->compensation_distance); | |
298 } | |
299 #endif | |
2967 | 300 |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
301 return dst_index; |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
302 } |