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.
26 #include "os_support.h"
29 /* fractional resampling */
30 uint32_t incr
; /* fractional increment */
33 /* integer down sample */
34 int iratio
; /* integer divison ratio */
37 } ReSampleChannelContext
;
39 struct ReSampleContext
{
40 ReSampleChannelContext channel_ctx
[2];
43 int input_channels
, output_channels
, filter_channels
;
48 #define FRAC (1 << FRAC_BITS)
50 static void init_mono_resample(ReSampleChannelContext
*s
, float ratio
)
53 s
->iratio
= (int)floorf(ratio
);
56 s
->incr
= (int)((ratio
/ s
->iratio
) * FRAC
);
59 s
->icount
= s
->iratio
;
61 s
->inv
= (FRAC
/ s
->iratio
);
64 /* fractional audio resampling */
65 static int fractional_resample(ReSampleChannelContext
*s
, short *output
, short *input
, int nb_samples
)
67 unsigned int frac
, incr
;
76 pend
= input
+ nb_samples
;
82 *q
++ = (l0
* (FRAC
- frac
) + l1
* frac
) >> FRAC_BITS
;
83 frac
= frac
+ s
->incr
;
84 while (frac
>= FRAC
) {
98 static int integer_downsample(ReSampleChannelContext
*s
, short *output
, short *input
, int nb_samples
)
104 pend
= input
+ nb_samples
;
113 *q
++ = (sum
* s
->inv
) >> FRAC_BITS
;
125 /* n1: number of samples */
126 static void stereo_to_mono(short *output
, short *input
, int n1
)
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;
143 q
[0] = (p
[0] + p
[1]) >> 1;
150 /* n1: number of samples */
151 static void mono_to_stereo(short *output
, short *input
, int n1
)
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
;
169 v
= p
[0]; q
[0] = v
; q
[1] = v
;
176 /* XXX: should use more abstract 'N' channels system */
177 static void stereo_split(short *output1
, short *output2
, short *input
, int n
)
182 *output1
++ = *input
++;
183 *output2
++ = *input
++;
187 static void stereo_mux(short *output
, short *input1
, short *input2
, int n
)
192 *output
++ = *input1
++;
193 *output
++ = *input2
++;
197 static int mono_resample(ReSampleChannelContext
*s
, short *output
, short *input
, int nb_samples
)
202 buf1
= (short*)av_malloc( nb_samples
* sizeof(short) );
204 /* first downsample by an integer factor with averaging filter */
207 nb_samples
= integer_downsample(s
, buftmp
, input
, nb_samples
);
212 /* then do a fractional resampling with linear interpolation */
213 if (s
->incr
!= FRAC
) {
214 nb_samples
= fractional_resample(s
, output
, buftmp
, nb_samples
);
216 memcpy(output
, buftmp
, nb_samples
* sizeof(short));
222 ReSampleContext
*audio_resample_init(int output_channels
, int input_channels
,
223 int output_rate
, int input_rate
)
228 if (output_channels
> 2 || input_channels
> 2)
231 s
= av_mallocz(sizeof(ReSampleContext
));
235 s
->ratio
= (float)output_rate
/ (float)input_rate
;
237 s
->input_channels
= input_channels
;
238 s
->output_channels
= output_channels
;
240 s
->filter_channels
= s
->input_channels
;
241 if (s
->output_channels
< s
->filter_channels
)
242 s
->filter_channels
= s
->output_channels
;
244 for(i
=0;i
<s
->filter_channels
;i
++) {
245 init_mono_resample(&s
->channel_ctx
[i
], s
->ratio
);
250 /* resample audio. 'nb_samples' is the number of input samples */
251 /* XXX: optimize it ! */
252 /* XXX: do it with polyphase filters, since the quality here is
253 HORRIBLE. Return the number of samples available in output */
254 int audio_resample(ReSampleContext
*s
, short *output
, short *input
, int nb_samples
)
259 short *buftmp2
[2], *buftmp3
[2];
262 if (s
->input_channels
== s
->output_channels
&& s
->ratio
== 1.0) {
264 memcpy(output
, input
, nb_samples
* s
->input_channels
* sizeof(short));
268 /* XXX: move those malloc to resample init code */
269 bufin
[0]= (short*) av_malloc( nb_samples
* sizeof(short) );
270 bufin
[1]= (short*) av_malloc( nb_samples
* sizeof(short) );
272 /* make some zoom to avoid round pb */
273 lenout
= (int)(nb_samples
* s
->ratio
) + 16;
274 bufout
[0]= (short*) av_malloc( lenout
* sizeof(short) );
275 bufout
[1]= (short*) av_malloc( lenout
* sizeof(short) );
277 if (s
->input_channels
== 2 &&
278 s
->output_channels
== 1) {
279 buftmp2
[0] = bufin
[0];
281 stereo_to_mono(buftmp2
[0], input
, nb_samples
);
282 } else if (s
->output_channels
== 2 && s
->input_channels
== 1) {
284 buftmp3
[0] = bufout
[0];
285 } else if (s
->output_channels
== 2) {
286 buftmp2
[0] = bufin
[0];
287 buftmp2
[1] = bufin
[1];
288 buftmp3
[0] = bufout
[0];
289 buftmp3
[1] = bufout
[1];
290 stereo_split(buftmp2
[0], buftmp2
[1], input
, nb_samples
);
296 /* resample each channel */
297 nb_samples1
= 0; /* avoid warning */
298 for(i
=0;i
<s
->filter_channels
;i
++) {
299 nb_samples1
= mono_resample(&s
->channel_ctx
[i
], buftmp3
[i
], buftmp2
[i
], nb_samples
);
302 if (s
->output_channels
== 2 && s
->input_channels
== 1) {
303 mono_to_stereo(output
, buftmp3
[0], nb_samples1
);
304 } else if (s
->output_channels
== 2) {
305 stereo_mux(output
, buftmp3
[0], buftmp3
[1], nb_samples1
);
316 void audio_resample_close(ReSampleContext
*s
)