annotate resample2.c @ 2109:84637c6ca74e libavcodec

various resampling fixes
author michael
date Wed, 30 Jun 2004 14:15:31 +0000
parents 76cdbe832239
children 7f88c429ad65
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 *
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
6 * 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
7 * License as published by the Free Software Foundation; either
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
9 *
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
11 * 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
12 * 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
13 * Lesser General Public License for more details.
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
14 *
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
18 *
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
19 */
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
20
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
21 /**
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
22 * @file resample2.c
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
23 * audio resampling
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
24 * @author Michael Niedermayer <michaelni@gmx.at>
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
25 */
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 #include "avcodec.h"
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
28 #include "common.h"
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
29
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
30 #define PHASE_SHIFT 10
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
31 #define PHASE_COUNT (1<<PHASE_SHIFT)
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
32 #define PHASE_MASK (PHASE_COUNT-1)
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
33 #define FILTER_SHIFT 15
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
34
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
35 typedef struct AVResampleContext{
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
36 short *filter_bank;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
37 int filter_length;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
38 int ideal_dst_incr;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
39 int dst_incr;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
40 int index;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
41 int frac;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
42 int src_incr;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
43 int compensation_distance;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
44 }AVResampleContext;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
45
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
46 /**
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
47 * 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
48 */
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
49 double bessel(double x){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
50 double v=1;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
51 double t=1;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
52 int i;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
53
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
54 for(i=1; i<50; i++){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
55 t *= i;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
56 v += pow(x*x/4, i)/(t*t);
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
57 }
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
58 return v;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
59 }
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
60
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
61 /**
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
62 * builds a polyphase filterbank.
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
63 * @param factor resampling factor
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
64 * @param scale wanted sum of coefficients for each filter
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
65 * @param type 0->cubic, 1->blackman nuttall windowed sinc, 2->kaiser windowed sinc beta=16
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
66 */
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
67 void av_build_filter(int16_t *filter, double factor, int tap_count, int phase_count, int scale, int type){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
68 int ph, i, v;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
69 double x, y, w, tab[tap_count];
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
70 const int center= (tap_count-1)/2;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
71
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
72 /* 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
73 if (factor > 1.0)
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
74 factor = 1.0;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
75
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
76 for(ph=0;ph<phase_count;ph++) {
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
77 double norm = 0;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
78 double e= 0;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
79 for(i=0;i<tap_count;i++) {
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
80 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
81 if (x == 0) y = 1.0;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
82 else y = sin(x) / x;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
83 switch(type){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
84 case 0:{
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
85 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
86 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
87 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
88 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
89 break;}
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
90 case 1:
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
91 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
92 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
93 break;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
94 case 2:
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
95 w = 2.0*x / (factor*tap_count*M_PI);
2083
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
96 y *= bessel(16*sqrt(FFMAX(1-w*w, 0)));
2082
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
97 break;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
98 }
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
99
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
100 tab[i] = y;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
101 norm += y;
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
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
104 /* 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
105 for(i=0;i<tap_count;i++) {
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
106 v = clip(lrintf(tab[i] * scale / norm) + e, -32768, 32767);
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
107 filter[ph * tap_count + i] = v;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
108 e += tab[i] * scale / norm - v;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
109 }
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
110 }
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
111 }
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
112
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
113 /**
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
114 * initalizes a audio resampler.
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
115 * note, if either rate is not a integer then simply scale both rates up so they are
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
116 */
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
117 AVResampleContext *av_resample_init(int out_rate, int in_rate){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
118 AVResampleContext *c= av_mallocz(sizeof(AVResampleContext));
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
119 double factor= FFMIN(out_rate / (double)in_rate, 1.0);
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
120
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
121 memset(c, 0, sizeof(AVResampleContext));
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
122
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
123 c->filter_length= ceil(16.0/factor);
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
124 c->filter_bank= av_mallocz(c->filter_length*(PHASE_COUNT+1)*sizeof(short));
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
125 av_build_filter(c->filter_bank, factor, c->filter_length, PHASE_COUNT, 1<<FILTER_SHIFT, 1);
2109
84637c6ca74e various resampling fixes
michael
parents: 2083
diff changeset
126 c->filter_bank[c->filter_length*PHASE_COUNT + (c->filter_length-1)/2 + 1]= (1<<FILTER_SHIFT)-1;
84637c6ca74e various resampling fixes
michael
parents: 2083
diff changeset
127 c->filter_bank[c->filter_length*PHASE_COUNT + (c->filter_length-1)/2 + 2]= 1;
2082
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 c->src_incr= out_rate;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
130 c->ideal_dst_incr= c->dst_incr= in_rate * PHASE_COUNT;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
131 c->index= -PHASE_COUNT*((c->filter_length-1)/2);
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 return c;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
134 }
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
135
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
136 void av_resample_close(AVResampleContext *c){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
137 av_freep(&c->filter_bank);
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
138 av_freep(&c);
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
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
141 void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){
2083
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
142 // 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
143 c->compensation_distance= compensation_distance;
2083
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
144 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
145 }
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
146
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
147 /**
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
148 * resamples.
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
149 * @param src an array of unconsumed samples
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
150 * @param consumed the number of samples of src which have been consumed are returned here
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
151 * @param src_size the number of unconsumed samples available
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
152 * @param dst_size the amount of space in samples available in dst
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
153 * @param update_ctx if this is 0 then the context wont be modified, that way several channels can be resampled with the same context
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
154 * @return the number of samples written in dst or -1 if an error occured
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
155 */
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
156 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
157 int dst_index, i;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
158 int index= c->index;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
159 int frac= c->frac;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
160 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
161 int dst_incr= c->dst_incr / c->src_incr;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
162
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
163 if(c->compensation_distance && c->compensation_distance < dst_size)
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
164 dst_size= c->compensation_distance;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
165
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
166 for(dst_index=0; dst_index < dst_size; dst_index++){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
167 short *filter= c->filter_bank + c->filter_length*(index & PHASE_MASK);
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
168 int sample_index= index >> PHASE_SHIFT;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
169 int val=0;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
170
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
171 if(sample_index < 0){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
172 for(i=0; i<c->filter_length; i++)
2109
84637c6ca74e various resampling fixes
michael
parents: 2083
diff changeset
173 val += src[ABS(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
174 }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
175 break;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
176 }else{
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
177 #if 0
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
178 int64_t v=0;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
179 int sub_phase= (frac<<12) / c->src_incr;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
180 for(i=0; i<c->filter_length; i++){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
181 int64_t coeff= filter[i]*(4096 - sub_phase) + filter[i + c->filter_length]*sub_phase;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
182 v += src[sample_index + i] * coeff;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
183 }
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
184 val= v>>12;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
185 #else
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
186 for(i=0; i<c->filter_length; i++){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
187 val += src[sample_index + i] * filter[i];
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
188 }
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
189 #endif
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
190 }
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
191
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
192 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
193 dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
194
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
195 frac += dst_incr_frac;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
196 index += dst_incr;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
197 if(frac >= c->src_incr){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
198 frac -= c->src_incr;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
199 index++;
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 }
2109
84637c6ca74e various resampling fixes
michael
parents: 2083
diff changeset
202 *consumed= FFMAX(index, 0) >> PHASE_SHIFT;
84637c6ca74e various resampling fixes
michael
parents: 2083
diff changeset
203 index= FFMIN(index, 0);
84637c6ca74e various resampling fixes
michael
parents: 2083
diff changeset
204
2082
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
205 if(update_ctx){
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
206 if(c->compensation_distance){
2083
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
207 c->compensation_distance -= dst_index;
2082
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
208 if(!c->compensation_distance)
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
209 c->dst_incr= c->ideal_dst_incr;
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 c->frac= frac;
2109
84637c6ca74e various resampling fixes
michael
parents: 2083
diff changeset
212 c->index= index;
2082
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
213 }
2083
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
214 #if 0
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
215 if(update_ctx && !c->compensation_distance){
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
216 #undef rand
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
217 av_resample_compensate(c, rand() % (8000*2) - 8000, 8000*2);
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
218 av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", c->dst_incr, c->ideal_dst_incr, c->compensation_distance);
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
219 }
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
220 #endif
76cdbe832239 avoid useless normalization and 10l fix
michael
parents: 2082
diff changeset
221
2082
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
222 return dst_index;
3dc9bbe1b152 polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
diff changeset
223 }