comparison resample.c @ 2082:3dc9bbe1b152 libavcodec

polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
author michael
date Thu, 17 Jun 2004 15:43:23 +0000
parents 932d306bf1dc
children db6a5e3e74a0
comparison
equal deleted inserted replaced
2081:d3015863f745 2082:3dc9bbe1b152
22 * Sample rate convertion for both audio and video. 22 * Sample rate convertion for both audio and video.
23 */ 23 */
24 24
25 #include "avcodec.h" 25 #include "avcodec.h"
26 26
27 typedef struct { 27 struct AVResampleContext;
28 /* fractional resampling */
29 uint32_t incr; /* fractional increment */
30 uint32_t frac;
31 int last_sample;
32 /* integer down sample */
33 int iratio; /* integer divison ratio */
34 int icount, isum;
35 int inv;
36 } ReSampleChannelContext;
37 28
38 struct ReSampleContext { 29 struct ReSampleContext {
39 ReSampleChannelContext channel_ctx[2]; 30 struct AVResampleContext *resample_context;
31 short *temp[2];
32 int temp_len;
40 float ratio; 33 float ratio;
41 /* channel convert */ 34 /* channel convert */
42 int input_channels, output_channels, filter_channels; 35 int input_channels, output_channels, filter_channels;
43 }; 36 };
44
45
46 #define FRAC_BITS 16
47 #define FRAC (1 << FRAC_BITS)
48
49 static void init_mono_resample(ReSampleChannelContext *s, float ratio)
50 {
51 ratio = 1.0 / ratio;
52 s->iratio = (int)floorf(ratio);
53 if (s->iratio == 0)
54 s->iratio = 1;
55 s->incr = (int)((ratio / s->iratio) * FRAC);
56 s->frac = FRAC;
57 s->last_sample = 0;
58 s->icount = s->iratio;
59 s->isum = 0;
60 s->inv = (FRAC / s->iratio);
61 }
62
63 /* fractional audio resampling */
64 static int fractional_resample(ReSampleChannelContext *s, short *output, short *input, int nb_samples)
65 {
66 unsigned int frac, incr;
67 int l0, l1;
68 short *q, *p, *pend;
69
70 l0 = s->last_sample;
71 incr = s->incr;
72 frac = s->frac;
73
74 p = input;
75 pend = input + nb_samples;
76 q = output;
77
78 l1 = *p++;
79 for(;;) {
80 /* interpolate */
81 *q++ = (l0 * (FRAC - frac) + l1 * frac) >> FRAC_BITS;
82 frac = frac + s->incr;
83 while (frac >= FRAC) {
84 frac -= FRAC;
85 if (p >= pend)
86 goto the_end;
87 l0 = l1;
88 l1 = *p++;
89 }
90 }
91 the_end:
92 s->last_sample = l1;
93 s->frac = frac;
94 return q - output;
95 }
96
97 static int integer_downsample(ReSampleChannelContext *s, short *output, short *input, int nb_samples)
98 {
99 short *q, *p, *pend;
100 int c, sum;
101
102 p = input;
103 pend = input + nb_samples;
104 q = output;
105
106 c = s->icount;
107 sum = s->isum;
108
109 for(;;) {
110 sum += *p++;
111 if (--c == 0) {
112 *q++ = (sum * s->inv) >> FRAC_BITS;
113 c = s->iratio;
114 sum = 0;
115 }
116 if (p >= pend)
117 break;
118 }
119 s->isum = sum;
120 s->icount = c;
121 return q - output;
122 }
123 37
124 /* n1: number of samples */ 38 /* n1: number of samples */
125 static void stereo_to_mono(short *output, short *input, int n1) 39 static void stereo_to_mono(short *output, short *input, int n1)
126 { 40 {
127 short *p, *q; 41 short *p, *q;
208 *output++ = 0; /* right surroud */ 122 *output++ = 0; /* right surroud */
209 *output++ = 0; /* low freq */ 123 *output++ = 0; /* low freq */
210 } 124 }
211 } 125 }
212 126
213 static int mono_resample(ReSampleChannelContext *s, short *output, short *input, int nb_samples)
214 {
215 short *buf1;
216 short *buftmp;
217
218 buf1= (short*)av_malloc( nb_samples * sizeof(short) );
219
220 /* first downsample by an integer factor with averaging filter */
221 if (s->iratio > 1) {
222 buftmp = buf1;
223 nb_samples = integer_downsample(s, buftmp, input, nb_samples);
224 } else {
225 buftmp = input;
226 }
227
228 /* then do a fractional resampling with linear interpolation */
229 if (s->incr != FRAC) {
230 nb_samples = fractional_resample(s, output, buftmp, nb_samples);
231 } else {
232 memcpy(output, buftmp, nb_samples * sizeof(short));
233 }
234 av_free(buf1);
235 return nb_samples;
236 }
237
238 ReSampleContext *audio_resample_init(int output_channels, int input_channels, 127 ReSampleContext *audio_resample_init(int output_channels, int input_channels,
239 int output_rate, int input_rate) 128 int output_rate, int input_rate)
240 { 129 {
241 ReSampleContext *s; 130 ReSampleContext *s;
242 int i; 131 int i;
269 * expand to 6 channels after the resampling. 158 * expand to 6 channels after the resampling.
270 */ 159 */
271 if(s->filter_channels>2) 160 if(s->filter_channels>2)
272 s->filter_channels = 2; 161 s->filter_channels = 2;
273 162
274 for(i=0;i<s->filter_channels;i++) { 163 s->resample_context= av_resample_init(output_rate, input_rate);
275 init_mono_resample(&s->channel_ctx[i], s->ratio); 164
276 }
277 return s; 165 return s;
278 } 166 }
279 167
280 /* resample audio. 'nb_samples' is the number of input samples */ 168 /* resample audio. 'nb_samples' is the number of input samples */
281 /* XXX: optimize it ! */ 169 /* XXX: optimize it ! */
282 /* XXX: do it with polyphase filters, since the quality here is
283 HORRIBLE. Return the number of samples available in output */
284 int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples) 170 int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples)
285 { 171 {
286 int i, nb_samples1; 172 int i, nb_samples1;
287 short *bufin[2]; 173 short *bufin[2];
288 short *bufout[2]; 174 short *bufout[2];
294 memcpy(output, input, nb_samples * s->input_channels * sizeof(short)); 180 memcpy(output, input, nb_samples * s->input_channels * sizeof(short));
295 return nb_samples; 181 return nb_samples;
296 } 182 }
297 183
298 /* XXX: move those malloc to resample init code */ 184 /* XXX: move those malloc to resample init code */
299 bufin[0]= (short*) av_malloc( nb_samples * sizeof(short) ); 185 for(i=0; i<s->filter_channels; i++){
300 bufin[1]= (short*) av_malloc( nb_samples * sizeof(short) ); 186 bufin[i]= (short*) av_malloc( (nb_samples + s->temp_len) * sizeof(short) );
187 memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short));
188 buftmp2[i] = bufin[i] + s->temp_len;
189 }
301 190
302 /* make some zoom to avoid round pb */ 191 /* make some zoom to avoid round pb */
303 lenout= (int)(nb_samples * s->ratio) + 16; 192 lenout= (int)(nb_samples * s->ratio) + 16;
304 bufout[0]= (short*) av_malloc( lenout * sizeof(short) ); 193 bufout[0]= (short*) av_malloc( lenout * sizeof(short) );
305 bufout[1]= (short*) av_malloc( lenout * sizeof(short) ); 194 bufout[1]= (short*) av_malloc( lenout * sizeof(short) );
306 195
307 if (s->input_channels == 2 && 196 if (s->input_channels == 2 &&
308 s->output_channels == 1) { 197 s->output_channels == 1) {
309 buftmp2[0] = bufin[0];
310 buftmp3[0] = output; 198 buftmp3[0] = output;
311 stereo_to_mono(buftmp2[0], input, nb_samples); 199 stereo_to_mono(buftmp2[0], input, nb_samples);
312 } else if (s->output_channels >= 2 && s->input_channels == 1) { 200 } else if (s->output_channels >= 2 && s->input_channels == 1) {
313 buftmp2[0] = input;
314 buftmp3[0] = bufout[0]; 201 buftmp3[0] = bufout[0];
202 memcpy(buftmp2[0], input, nb_samples*sizeof(short));
315 } else if (s->output_channels >= 2) { 203 } else if (s->output_channels >= 2) {
316 buftmp2[0] = bufin[0];
317 buftmp2[1] = bufin[1];
318 buftmp3[0] = bufout[0]; 204 buftmp3[0] = bufout[0];
319 buftmp3[1] = bufout[1]; 205 buftmp3[1] = bufout[1];
320 stereo_split(buftmp2[0], buftmp2[1], input, nb_samples); 206 stereo_split(buftmp2[0], buftmp2[1], input, nb_samples);
321 } else { 207 } else {
322 buftmp2[0] = input;
323 buftmp3[0] = output; 208 buftmp3[0] = output;
324 } 209 memcpy(buftmp2[0], input, nb_samples*sizeof(short));
210 }
211
212 nb_samples += s->temp_len;
325 213
326 /* resample each channel */ 214 /* resample each channel */
327 nb_samples1 = 0; /* avoid warning */ 215 nb_samples1 = 0; /* avoid warning */
328 for(i=0;i<s->filter_channels;i++) { 216 for(i=0;i<s->filter_channels;i++) {
329 nb_samples1 = mono_resample(&s->channel_ctx[i], buftmp3[i], buftmp2[i], nb_samples); 217 int consumed;
218 int is_last= i+1 == s->filter_channels;
219
220 nb_samples1 = av_resample(s->resample_context, buftmp3[i], bufin[i], &consumed, nb_samples, lenout, is_last);
221 s->temp_len= nb_samples - consumed;
222 s->temp[i]= av_realloc(s->temp[i], s->temp_len*sizeof(short));
223 memcpy(s->temp[i], bufin[i] + consumed, s->temp_len*sizeof(short));
330 } 224 }
331 225
332 if (s->output_channels == 2 && s->input_channels == 1) { 226 if (s->output_channels == 2 && s->input_channels == 1) {
333 mono_to_stereo(output, buftmp3[0], nb_samples1); 227 mono_to_stereo(output, buftmp3[0], nb_samples1);
334 } else if (s->output_channels == 2) { 228 } else if (s->output_channels == 2) {
345 return nb_samples1; 239 return nb_samples1;
346 } 240 }
347 241
348 void audio_resample_close(ReSampleContext *s) 242 void audio_resample_close(ReSampleContext *s)
349 { 243 {
244 av_resample_close(s->resample_context);
245 av_freep(&s->temp[0]);
246 av_freep(&s->temp[1]);
350 av_free(s); 247 av_free(s);
351 } 248 }