Statistics
| Branch: | Revision:

ffmpeg / libavcodec / resample.c @ f259747b

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  02111-1307  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
}