ffmpeg / libavcodec / resample.c @ 742d87d6
History  View  Annotate  Download (8.98 KB)
1 
/*


2 
* Sample rate convertion for both audio and video

3 
* Copyright (c) 2000 Fabrice Bellard.

4 
*

5 
* This library is free software; you can redistribute it and/or

6 
* modify it under the terms of the GNU Lesser General Public

7 
* License as published by the Free Software Foundation; either

8 
* version 2 of the License, or (at your option) any later version.

9 
*

10 
* This library is distributed in the hope that it will be useful,

11 
* but WITHOUT ANY WARRANTY; without even the implied warranty of

12 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

13 
* Lesser General Public License for more details.

14 
*

15 
* You should have received a copy of the GNU Lesser General Public

16 
* License along with this library; if not, write to the Free Software

17 
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 021111307 USA

18 
*/

19  
20 
/**

21 
* @file resample.c

22 
* Sample rate convertion for both audio and video.

23 
*/

24  
25 
#include "avcodec.h" 
26  
27 
typedef struct { 
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  
38 
struct ReSampleContext {

39 
ReSampleChannelContext channel_ctx[2];

40 
float ratio;

41 
/* channel convert */

42 
int input_channels, output_channels, filter_channels;

43 
}; 
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  
124 
/* n1: number of samples */

125 
static void stereo_to_mono(short *output, short *input, int n1) 
126 
{ 
127 
short *p, *q;

128 
int n = n1;

129  
130 
p = input; 
131 
q = output; 
132 
while (n >= 4) { 
133 
q[0] = (p[0] + p[1]) >> 1; 
134 
q[1] = (p[2] + p[3]) >> 1; 
135 
q[2] = (p[4] + p[5]) >> 1; 
136 
q[3] = (p[6] + p[7]) >> 1; 
137 
q += 4;

138 
p += 8;

139 
n = 4;

140 
} 
141 
while (n > 0) { 
142 
q[0] = (p[0] + p[1]) >> 1; 
143 
q++; 
144 
p += 2;

145 
n; 
146 
} 
147 
} 
148  
149 
/* n1: number of samples */

150 
static void mono_to_stereo(short *output, short *input, int n1) 
151 
{ 
152 
short *p, *q;

153 
int n = n1;

154 
int v;

155  
156 
p = input; 
157 
q = output; 
158 
while (n >= 4) { 
159 
v = p[0]; q[0] = v; q[1] = v; 
160 
v = p[1]; q[2] = v; q[3] = v; 
161 
v = p[2]; q[4] = v; q[5] = v; 
162 
v = p[3]; q[6] = v; q[7] = v; 
163 
q += 8;

164 
p += 4;

165 
n = 4;

166 
} 
167 
while (n > 0) { 
168 
v = p[0]; q[0] = v; q[1] = v; 
169 
q += 2;

170 
p += 1;

171 
n; 
172 
} 
173 
} 
174  
175 
/* XXX: should use more abstract 'N' channels system */

176 
static void stereo_split(short *output1, short *output2, short *input, int n) 
177 
{ 
178 
int i;

179  
180 
for(i=0;i<n;i++) { 
181 
*output1++ = *input++; 
182 
*output2++ = *input++; 
183 
} 
184 
} 
185  
186 
static void stereo_mux(short *output, short *input1, short *input2, int n) 
187 
{ 
188 
int i;

189  
190 
for(i=0;i<n;i++) { 
191 
*output++ = *input1++; 
192 
*output++ = *input2++; 
193 
} 
194 
} 
195  
196 
static void ac3_5p1_mux(short *output, short *input1, short *input2, int n) 
197 
{ 
198 
int i;

199 
short l,r;

200  
201 
for(i=0;i<n;i++) { 
202 
l=*input1++; 
203 
r=*input2++; 
204 
*output++ = l; /* left */

205 
*output++ = (l/2)+(r/2); /* center */ 
206 
*output++ = r; /* right */

207 
*output++ = 0; /* left surround */ 
208 
*output++ = 0; /* right surroud */ 
209 
*output++ = 0; /* low freq */ 
210 
} 
211 
} 
212  
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, 
239 
int output_rate, int input_rate) 
240 
{ 
241 
ReSampleContext *s; 
242 
int i;

243 

244 
if ( input_channels > 2) 
245 
{ 
246 
printf("Resampling with input channels greater than 2 unsupported.");

247 
return NULL; 
248 
} 
249  
250 
s = av_mallocz(sizeof(ReSampleContext));

251 
if (!s)

252 
{ 
253 
printf("Can't allocate memory for resample context.");

254 
return NULL; 
255 
} 
256  
257 
s>ratio = (float)output_rate / (float)input_rate; 
258 

259 
s>input_channels = input_channels; 
260 
s>output_channels = output_channels; 
261 

262 
s>filter_channels = s>input_channels; 
263 
if (s>output_channels < s>filter_channels)

264 
s>filter_channels = s>output_channels; 
265  
266 
/*

267 
* ac3 output is the only case where filter_channels could be greater than 2.

268 
* input channels can't be greater than 2, so resample the 2 channels and then

269 
* expand to 6 channels after the resampling.

270 
*/

271 
if(s>filter_channels>2) 
272 
s>filter_channels = 2;

273  
274 
for(i=0;i<s>filter_channels;i++) { 
275 
init_mono_resample(&s>channel_ctx[i], s>ratio); 
276 
} 
277 
return s;

278 
} 
279  
280 
/* resample audio. 'nb_samples' is the number of input samples */

281 
/* 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) 
285 
{ 
286 
int i, nb_samples1;

287 
short *bufin[2]; 
288 
short *bufout[2]; 
289 
short *buftmp2[2], *buftmp3[2]; 
290 
int lenout;

291  
292 
if (s>input_channels == s>output_channels && s>ratio == 1.0) { 
293 
/* nothing to do */

294 
memcpy(output, input, nb_samples * s>input_channels * sizeof(short)); 
295 
return nb_samples;

296 
} 
297  
298 
/* XXX: move those malloc to resample init code */

299 
bufin[0]= (short*) av_malloc( nb_samples * sizeof(short) ); 
300 
bufin[1]= (short*) av_malloc( nb_samples * sizeof(short) ); 
301 

302 
/* make some zoom to avoid round pb */

303 
lenout= (int)(nb_samples * s>ratio) + 16; 
304 
bufout[0]= (short*) av_malloc( lenout * sizeof(short) ); 
305 
bufout[1]= (short*) av_malloc( lenout * sizeof(short) ); 
306  
307 
if (s>input_channels == 2 && 
308 
s>output_channels == 1) {

309 
buftmp2[0] = bufin[0]; 
310 
buftmp3[0] = output;

311 
stereo_to_mono(buftmp2[0], input, nb_samples);

312 
} else if (s>output_channels >= 2 && s>input_channels == 1) { 
313 
buftmp2[0] = input;

314 
buftmp3[0] = bufout[0]; 
315 
} else if (s>output_channels >= 2) { 
316 
buftmp2[0] = bufin[0]; 
317 
buftmp2[1] = bufin[1]; 
318 
buftmp3[0] = bufout[0]; 
319 
buftmp3[1] = bufout[1]; 
320 
stereo_split(buftmp2[0], buftmp2[1], input, nb_samples); 
321 
} else {

322 
buftmp2[0] = input;

323 
buftmp3[0] = output;

324 
} 
325  
326 
/* resample each channel */

327 
nb_samples1 = 0; /* avoid warning */ 
328 
for(i=0;i<s>filter_channels;i++) { 
329 
nb_samples1 = mono_resample(&s>channel_ctx[i], buftmp3[i], buftmp2[i], nb_samples); 
330 
} 
331  
332 
if (s>output_channels == 2 && s>input_channels == 1) { 
333 
mono_to_stereo(output, buftmp3[0], nb_samples1);

334 
} else if (s>output_channels == 2) { 
335 
stereo_mux(output, buftmp3[0], buftmp3[1], nb_samples1); 
336 
} else if (s>output_channels == 6) { 
337 
ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1); 
338 
} 
339  
340 
av_free(bufin[0]);

341 
av_free(bufin[1]);

342  
343 
av_free(bufout[0]);

344 
av_free(bufout[1]);

345 
return nb_samples1;

346 
} 
347  
348 
void audio_resample_close(ReSampleContext *s)

349 
{ 
350 
av_free(s); 
351 
} 