Mercurial > libavcodec.hg
annotate resample2.c @ 9896:bbefbca72722 libavcodec
Drop code that attempts to decode frames that are prefixed by junk.
Too often it ends up decoding random data into noise without detecting
it (for example after seeking of some MP3 data with oddly often occurring
startcode emulation).
Fixes issue1154.
| author | michael |
|---|---|
| date | Tue, 30 Jun 2009 03:57:27 +0000 |
| parents | fff66291d84d |
| children | 002cd0505064 |
| 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; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
79 double t=1; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
80 int i; |
| 2967 | 81 |
|
4701
5fa551fb7640
optimize bessel function instead of trusting gcc to do trivial optimizations (as gcc doesnt ...)
michael
parents:
4700
diff
changeset
|
82 x= x*x/4; |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
83 for(i=1; i<50; i++){ |
|
4701
5fa551fb7640
optimize bessel function instead of trusting gcc to do trivial optimizations (as gcc doesnt ...)
michael
parents:
4700
diff
changeset
|
84 t *= x/(i*i); |
|
5fa551fb7640
optimize bessel function instead of trusting gcc to do trivial optimizations (as gcc doesnt ...)
michael
parents:
4700
diff
changeset
|
85 v += t; |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
86 } |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
87 return v; |
|
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 |
|
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 * builds a polyphase filterbank. |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
92 * @param factor resampling factor |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
93 * @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
|
94 * @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
|
95 */ |
|
2304
09b2ef0ac97d
make filter size, int32/int16 and a few other things selectable at compiletime
michael
parents:
2303
diff
changeset
|
96 void av_build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){ |
| 4822 | 97 int ph, i; |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
98 double x, y, w, tab[tap_count]; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
99 const int center= (tap_count-1)/2; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
100 |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
101 /* 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
|
102 if (factor > 1.0) |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
103 factor = 1.0; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
104 |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
105 for(ph=0;ph<phase_count;ph++) { |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
106 double norm = 0; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
107 for(i=0;i<tap_count;i++) { |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
108 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
|
109 if (x == 0) y = 1.0; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
110 else y = sin(x) / x; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
111 switch(type){ |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
112 case 0:{ |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
113 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
|
114 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
|
115 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
|
116 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
|
117 break;} |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
118 case 1: |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
119 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
|
120 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
|
121 break; |
|
4699
4040ca52670a
make kaiser windows with other beta than 16 available
michael
parents:
4697
diff
changeset
|
122 default: |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
123 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
|
124 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
|
125 break; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
126 } |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
127 |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
128 tab[i] = y; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
129 norm += y; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
130 } |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
131 |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
132 /* 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
|
133 for(i=0;i<tap_count;i++) { |
| 4702 | 134 #ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE |
| 135 filter[ph * tap_count + i] = tab[i] / norm; | |
| 136 #else | |
| 137 filter[ph * tap_count + i] = av_clip(lrintf(tab[i] * scale / norm), FELEM_MIN, FELEM_MAX); | |
| 138 #endif | |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
139 } |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
140 } |
| 4695 | 141 #if 0 |
| 142 { | |
| 143 #define LEN 1024 | |
| 144 int j,k; | |
| 145 double sine[LEN + tap_count]; | |
| 146 double filtered[LEN]; | |
| 147 double maxff=-2, minff=2, maxsf=-2, minsf=2; | |
| 148 for(i=0; i<LEN; i++){ | |
| 149 double ss=0, sf=0, ff=0; | |
| 150 for(j=0; j<LEN+tap_count; j++) | |
| 151 sine[j]= cos(i*j*M_PI/LEN); | |
| 152 for(j=0; j<LEN; j++){ | |
| 153 double sum=0; | |
| 154 ph=0; | |
| 155 for(k=0; k<tap_count; k++) | |
| 156 sum += filter[ph * tap_count + k] * sine[k+j]; | |
| 157 filtered[j]= sum / (1<<FILTER_SHIFT); | |
| 158 ss+= sine[j + center] * sine[j + center]; | |
| 159 ff+= filtered[j] * filtered[j]; | |
| 160 sf+= sine[j + center] * filtered[j]; | |
| 161 } | |
| 162 ss= sqrt(2*ss/LEN); | |
| 163 ff= sqrt(2*ff/LEN); | |
| 164 sf= 2*sf/LEN; | |
| 165 maxff= FFMAX(maxff, ff); | |
| 166 minff= FFMIN(minff, ff); | |
| 167 maxsf= FFMAX(maxsf, sf); | |
| 168 minsf= FFMIN(minsf, sf); | |
| 169 if(i%11==0){ | |
| 4702 | 170 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 | 171 minff=minsf= 2; |
| 172 maxff=maxsf= -2; | |
| 173 } | |
| 174 } | |
| 175 } | |
| 176 #endif | |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
177 } |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
178 |
| 2308 | 179 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
|
180 AVResampleContext *c= av_mallocz(sizeof(AVResampleContext)); |
| 2308 | 181 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
|
182 int phase_count= 1<<phase_shift; |
| 2967 | 183 |
|
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
184 c->phase_shift= phase_shift; |
|
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
185 c->phase_mask= phase_count-1; |
|
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
186 c->linear= linear; |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
187 |
|
2835
d4c4b84e0fac
minor fixes for invalid audio data patch by (Wolfram Gloger: wmglo, dent med uni-muenchen de)
michael
parents:
2426
diff
changeset
|
188 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
|
189 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
|
190 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
|
191 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
|
192 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
|
193 |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
194 c->src_incr= out_rate; |
|
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
195 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
|
196 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
|
197 |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
198 return c; |
|
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 |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
201 void av_resample_close(AVResampleContext *c){ |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
202 av_freep(&c->filter_bank); |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
203 av_freep(&c); |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
204 } |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
205 |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
206 void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){ |
| 2083 | 207 // 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
|
208 c->compensation_distance= compensation_distance; |
| 2083 | 209 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
|
210 } |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
211 |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
212 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
|
213 int dst_index, i; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
214 int index= c->index; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
215 int frac= c->frac; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
216 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
|
217 int dst_incr= c->dst_incr / c->src_incr; |
| 2277 | 218 int compensation_distance= c->compensation_distance; |
|
2405
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
219 |
| 2403 | 220 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
|
221 int64_t index2= ((int64_t)index)<<32; |
|
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
222 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
|
223 dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr); |
| 2967 | 224 |
| 2403 | 225 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
|
226 dst[dst_index] = src[index2>>32]; |
|
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
227 index2 += incr; |
| 2403 | 228 } |
|
2405
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
229 frac += dst_index * dst_incr_frac; |
|
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
230 index += dst_index * dst_incr; |
|
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
231 index += frac / c->src_incr; |
|
21c5ef8a4ff7
faster and slightly less accurate nearest neighbor resampler
michael
parents:
2403
diff
changeset
|
232 frac %= c->src_incr; |
| 2403 | 233 }else{ |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
234 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
|
235 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
|
236 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
|
237 FELEM2 val=0; |
| 2967 | 238 |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
239 if(sample_index < 0){ |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
240 for(i=0; i<c->filter_length; i++) |
| 4001 | 241 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
|
242 }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
|
243 break; |
|
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
244 }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
|
245 FELEM2 v2=0; |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
246 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
|
247 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
|
248 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
|
249 } |
|
4707
441cded6920c
optimize linear filter coeff interpolation code, this also makes the code less prone to overflows
michael
parents:
4703
diff
changeset
|
250 val+=(v2-val)*(FELEML)frac / c->src_incr; |
|
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
251 }else{ |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
252 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
|
253 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
|
254 } |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
255 } |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
256 |
| 4702 | 257 #ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE |
| 5523 | 258 dst[dst_index] = av_clip_int16(lrintf(val)); |
| 4702 | 259 #else |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
260 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
|
261 dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val; |
| 4702 | 262 #endif |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
263 |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
264 frac += dst_incr_frac; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
265 index += dst_incr; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
266 if(frac >= c->src_incr){ |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
267 frac -= c->src_incr; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
268 index++; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
269 } |
| 2277 | 270 |
| 271 if(dst_index + 1 == compensation_distance){ | |
| 272 compensation_distance= 0; | |
| 273 dst_incr_frac= c->ideal_dst_incr % c->src_incr; | |
| 274 dst_incr= c->ideal_dst_incr / c->src_incr; | |
| 275 } | |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
276 } |
| 2403 | 277 } |
|
2306
072fc321fbe6
make most resample filter parameters selectable at runtime
michael
parents:
2305
diff
changeset
|
278 *consumed= FFMAX(index, 0) >> c->phase_shift; |
|
2307
df3e4a8e6aac
100l (dont reset the sample position at the block end)
michael
parents:
2306
diff
changeset
|
279 if(index>=0) index &= c->phase_mask; |
| 2109 | 280 |
| 2277 | 281 if(compensation_distance){ |
| 282 compensation_distance -= dst_index; | |
| 283 assert(compensation_distance > 0); | |
| 284 } | |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
285 if(update_ctx){ |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
286 c->frac= frac; |
| 2109 | 287 c->index= index; |
| 2277 | 288 c->dst_incr= dst_incr_frac + c->src_incr*dst_incr; |
| 289 c->compensation_distance= compensation_distance; | |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
290 } |
| 2967 | 291 #if 0 |
| 2083 | 292 if(update_ctx && !c->compensation_distance){ |
| 293 #undef rand | |
| 294 av_resample_compensate(c, rand() % (8000*2) - 8000, 8000*2); | |
| 295 av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", c->dst_incr, c->ideal_dst_incr, c->compensation_distance); | |
| 296 } | |
| 297 #endif | |
| 2967 | 298 |
|
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
299 return dst_index; |
|
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff
changeset
|
300 } |
