2 * Sample rate convertion for both audio and video
3 * Copyright (c) 2000 Fabrice Bellard.
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.
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.
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 02111-1307 USA
22 * Sample rate convertion for both audio and video.
27 #if defined (CONFIG_OS2)
28 #define floorf(n) floor(n)
32 /* fractional resampling */
33 uint32_t incr
; /* fractional increment */
36 /* integer down sample */
37 int iratio
; /* integer divison ratio */
40 } ReSampleChannelContext
;
42 struct ReSampleContext
{
43 ReSampleChannelContext channel_ctx
[2];
46 int input_channels
, output_channels
, filter_channels
;
51 #define FRAC (1 << FRAC_BITS)
53 static void init_mono_resample(ReSampleChannelContext
*s
, float ratio
)
56 s
->iratio
= (int)floorf(ratio
);
59 s
->incr
= (int)((ratio
/ s
->iratio
) * FRAC
);
62 s
->icount
= s
->iratio
;
64 s
->inv
= (FRAC
/ s
->iratio
);
67 /* fractional audio resampling */
68 static int fractional_resample(ReSampleChannelContext
*s
, short *output
, short *input
, int nb_samples
)
70 unsigned int frac
, incr
;
79 pend
= input
+ nb_samples
;
85 *q
++ = (l0
* (FRAC
- frac
) + l1
* frac
) >> FRAC_BITS
;
86 frac
= frac
+ s
->incr
;
87 while (frac
>= FRAC
) {
101 static int integer_downsample(ReSampleChannelContext
*s
, short *output
, short *input
, int nb_samples
)
107 pend
= input
+ nb_samples
;
116 *q
++ = (sum
* s
->inv
) >> FRAC_BITS
;
128 /* n1: number of samples */
129 static void stereo_to_mono(short *output
, short *input
, int n1
)
137 q
[0] = (p
[0] + p
[1]) >> 1;
138 q
[1] = (p
[2] + p
[3]) >> 1;
139 q
[2] = (p
[4] + p
[5]) >> 1;
140 q
[3] = (p
[6] + p
[7]) >> 1;
146 q
[0] = (p
[0] + p
[1]) >> 1;
153 /* n1: number of samples */
154 static void mono_to_stereo(short *output
, short *input
, int n1
)
163 v
= p
[0]; q
[0] = v
; q
[1] = v
;
164 v
= p
[1]; q
[2] = v
; q
[3] = v
;
165 v
= p
[2]; q
[4] = v
; q
[5] = v
;
166 v
= p
[3]; q
[6] = v
; q
[7] = v
;
172 v
= p
[0]; q
[0] = v
; q
[1] = v
;
179 /* XXX: should use more abstract 'N' channels system */
180 static void stereo_split(short *output1
, short *output2
, short *input
, int n
)
185 *output1
++ = *input
++;
186 *output2
++ = *input
++;
190 static void stereo_mux(short *output
, short *input1
, short *input2
, int n
)
195 *output
++ = *input1
++;
196 *output
++ = *input2
++;
200 static int mono_resample(ReSampleChannelContext
*s
, short *output
, short *input
, int nb_samples
)
205 buf1
= (short*)av_malloc( nb_samples
* sizeof(short) );
207 /* first downsample by an integer factor with averaging filter */
210 nb_samples
= integer_downsample(s
, buftmp
, input
, nb_samples
);
215 /* then do a fractional resampling with linear interpolation */
216 if (s
->incr
!= FRAC
) {
217 nb_samples
= fractional_resample(s
, output
, buftmp
, nb_samples
);
219 memcpy(output
, buftmp
, nb_samples
* sizeof(short));
225 ReSampleContext
*audio_resample_init(int output_channels
, int input_channels
,
226 int output_rate
, int input_rate
)
231 if (output_channels
> 2 || input_channels
> 2)
234 s
= av_mallocz(sizeof(ReSampleContext
));
238 s
->ratio
= (float)output_rate
/ (float)input_rate
;
240 s
->input_channels
= input_channels
;
241 s
->output_channels
= output_channels
;
243 s
->filter_channels
= s
->input_channels
;
244 if (s
->output_channels
< s
->filter_channels
)
245 s
->filter_channels
= s
->output_channels
;
247 for(i
=0;i
<s
->filter_channels
;i
++) {
248 init_mono_resample(&s
->channel_ctx
[i
], s
->ratio
);
253 /* resample audio. 'nb_samples' is the number of input samples */
254 /* XXX: optimize it ! */
255 /* XXX: do it with polyphase filters, since the quality here is
256 HORRIBLE. Return the number of samples available in output */
257 int audio_resample(ReSampleContext
*s
, short *output
, short *input
, int nb_samples
)
262 short *buftmp2
[2], *buftmp3
[2];
265 if (s
->input_channels
== s
->output_channels
&& s
->ratio
== 1.0) {
267 memcpy(output
, input
, nb_samples
* s
->input_channels
* sizeof(short));
271 /* XXX: move those malloc to resample init code */
272 bufin
[0]= (short*) av_malloc( nb_samples
* sizeof(short) );
273 bufin
[1]= (short*) av_malloc( nb_samples
* sizeof(short) );
275 /* make some zoom to avoid round pb */
276 lenout
= (int)(nb_samples
* s
->ratio
) + 16;
277 bufout
[0]= (short*) av_malloc( lenout
* sizeof(short) );
278 bufout
[1]= (short*) av_malloc( lenout
* sizeof(short) );
280 if (s
->input_channels
== 2 &&
281 s
->output_channels
== 1) {
282 buftmp2
[0] = bufin
[0];
284 stereo_to_mono(buftmp2
[0], input
, nb_samples
);
285 } else if (s
->output_channels
== 2 && s
->input_channels
== 1) {
287 buftmp3
[0] = bufout
[0];
288 } else if (s
->output_channels
== 2) {
289 buftmp2
[0] = bufin
[0];
290 buftmp2
[1] = bufin
[1];
291 buftmp3
[0] = bufout
[0];
292 buftmp3
[1] = bufout
[1];
293 stereo_split(buftmp2
[0], buftmp2
[1], input
, nb_samples
);
299 /* resample each channel */
300 nb_samples1
= 0; /* avoid warning */
301 for(i
=0;i
<s
->filter_channels
;i
++) {
302 nb_samples1
= mono_resample(&s
->channel_ctx
[i
], buftmp3
[i
], buftmp2
[i
], nb_samples
);
305 if (s
->output_channels
== 2 && s
->input_channels
== 1) {
306 mono_to_stereo(output
, buftmp3
[0], nb_samples1
);
307 } else if (s
->output_channels
== 2) {
308 stereo_mux(output
, buftmp3
[0], buftmp3
[1], nb_samples1
);
319 void audio_resample_close(ReSampleContext
*s
)