ffmpeg / libavcodec / resample.c @ 2d5e962b
History  View  Annotate  Download (9 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 
#include "os_support.h" 
27  
28 
typedef struct { 
29 
/* fractional resampling */

30 
uint32_t incr; /* fractional increment */

31 
uint32_t frac; 
32 
int last_sample;

33 
/* integer down sample */

34 
int iratio; /* integer divison ratio */ 
35 
int icount, isum;

36 
int inv;

37 
} ReSampleChannelContext; 
38  
39 
struct ReSampleContext {

40 
ReSampleChannelContext channel_ctx[2];

41 
float ratio;

42 
/* channel convert */

43 
int input_channels, output_channels, filter_channels;

44 
}; 
45  
46  
47 
#define FRAC_BITS 16 
48 
#define FRAC (1 << FRAC_BITS) 
49  
50 
static void init_mono_resample(ReSampleChannelContext *s, float ratio) 
51 
{ 
52 
ratio = 1.0 / ratio; 
53 
s>iratio = (int)floorf(ratio);

54 
if (s>iratio == 0) 
55 
s>iratio = 1;

56 
s>incr = (int)((ratio / s>iratio) * FRAC);

57 
s>frac = FRAC; 
58 
s>last_sample = 0;

59 
s>icount = s>iratio; 
60 
s>isum = 0;

61 
s>inv = (FRAC / s>iratio); 
62 
} 
63  
64 
/* fractional audio resampling */

65 
static int fractional_resample(ReSampleChannelContext *s, short *output, short *input, int nb_samples) 
66 
{ 
67 
unsigned int frac, incr; 
68 
int l0, l1;

69 
short *q, *p, *pend;

70  
71 
l0 = s>last_sample; 
72 
incr = s>incr; 
73 
frac = s>frac; 
74  
75 
p = input; 
76 
pend = input + nb_samples; 
77 
q = output; 
78  
79 
l1 = *p++; 
80 
for(;;) {

81 
/* interpolate */

82 
*q++ = (l0 * (FRAC  frac) + l1 * frac) >> FRAC_BITS; 
83 
frac = frac + s>incr; 
84 
while (frac >= FRAC) {

85 
frac = FRAC; 
86 
if (p >= pend)

87 
goto the_end;

88 
l0 = l1; 
89 
l1 = *p++; 
90 
} 
91 
} 
92 
the_end:

93 
s>last_sample = l1; 
94 
s>frac = frac; 
95 
return q  output;

96 
} 
97  
98 
static int integer_downsample(ReSampleChannelContext *s, short *output, short *input, int nb_samples) 
99 
{ 
100 
short *q, *p, *pend;

101 
int c, sum;

102  
103 
p = input; 
104 
pend = input + nb_samples; 
105 
q = output; 
106  
107 
c = s>icount; 
108 
sum = s>isum; 
109  
110 
for(;;) {

111 
sum += *p++; 
112 
if (c == 0) { 
113 
*q++ = (sum * s>inv) >> FRAC_BITS; 
114 
c = s>iratio; 
115 
sum = 0;

116 
} 
117 
if (p >= pend)

118 
break;

119 
} 
120 
s>isum = sum; 
121 
s>icount = c; 
122 
return q  output;

123 
} 
124  
125 
/* n1: number of samples */

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

129 
int n = n1;

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

139 
p += 8;

140 
n = 4;

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

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

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

154 
int n = n1;

155 
int v;

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

165 
p += 4;

166 
n = 4;

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

171 
p += 1;

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

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

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

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

200 
short l,r;

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

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

208 
*output++ = 0; /* left surround */ 
209 
*output++ = 0; /* right surroud */ 
210 
*output++ = 0; /* low freq */ 
211 
} 
212 
} 
213  
214 
static int mono_resample(ReSampleChannelContext *s, short *output, short *input, int nb_samples) 
215 
{ 
216 
short *buf1;

217 
short *buftmp;

218  
219 
buf1= (short*)av_malloc( nb_samples * sizeof(short) ); 
220  
221 
/* first downsample by an integer factor with averaging filter */

222 
if (s>iratio > 1) { 
223 
buftmp = buf1; 
224 
nb_samples = integer_downsample(s, buftmp, input, nb_samples); 
225 
} else {

226 
buftmp = input; 
227 
} 
228  
229 
/* then do a fractional resampling with linear interpolation */

230 
if (s>incr != FRAC) {

231 
nb_samples = fractional_resample(s, output, buftmp, nb_samples); 
232 
} else {

233 
memcpy(output, buftmp, nb_samples * sizeof(short)); 
234 
} 
235 
av_free(buf1); 
236 
return nb_samples;

237 
} 
238  
239 
ReSampleContext *audio_resample_init(int output_channels, int input_channels, 
240 
int output_rate, int input_rate) 
241 
{ 
242 
ReSampleContext *s; 
243 
int i;

244 

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

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

252 
if (!s)

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

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

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

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

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

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

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

270 
* expand to 6 channels after the resampling.

271 
*/

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

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

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

282 
/* XXX: optimize it ! */

283 
/* XXX: do it with polyphase filters, since the quality here is

284 
HORRIBLE. Return the number of samples available in output */

285 
int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples) 
286 
{ 
287 
int i, nb_samples1;

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

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

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

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

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

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

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

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

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

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

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

323 
buftmp2[0] = input;

324 
buftmp3[0] = output;

325 
} 
326  
327 
/* resample each channel */

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

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

342 
av_free(bufin[1]);

343  
344 
av_free(bufout[0]);

345 
av_free(bufout[1]);

346 
return nb_samples1;

347 
} 
348  
349 
void audio_resample_close(ReSampleContext *s)

350 
{ 
351 
av_free(s); 
352 
} 