annotate resample.c @ 229:f418b5c5ff67 libavcodec

PATCH by Rik Snel <rsnel@cube.dyndns.org> this patch enhances the jpeg header writer. It can be asked to omit quantisation and huffman tables and it can write different horizontal and vertical sampling factors. (the last thing is useless for libavcodec itself (because libavcodec only handles YUV420P at ecoder level), but the values are initialized so that operation of libavcodec is not impaired)
author arpi_esp
date Sat, 09 Feb 2002 01:23:41 +0000
parents 5aa6292a1660
children 3007abcbc510
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
1 /*
986e461dc072 Initial revision
glantau
parents:
diff changeset
2 * Sample rate convertion for both audio and video
986e461dc072 Initial revision
glantau
parents:
diff changeset
3 * Copyright (c) 2000 Gerard Lantau.
986e461dc072 Initial revision
glantau
parents:
diff changeset
4 *
986e461dc072 Initial revision
glantau
parents:
diff changeset
5 * This program is free software; you can redistribute it and/or modify
986e461dc072 Initial revision
glantau
parents:
diff changeset
6 * it under the terms of the GNU General Public License as published by
986e461dc072 Initial revision
glantau
parents:
diff changeset
7 * the Free Software Foundation; either version 2 of the License, or
986e461dc072 Initial revision
glantau
parents:
diff changeset
8 * (at your option) any later version.
986e461dc072 Initial revision
glantau
parents:
diff changeset
9 *
986e461dc072 Initial revision
glantau
parents:
diff changeset
10 * This program is distributed in the hope that it will be useful,
986e461dc072 Initial revision
glantau
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
986e461dc072 Initial revision
glantau
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
986e461dc072 Initial revision
glantau
parents:
diff changeset
13 * GNU General Public License for more details.
986e461dc072 Initial revision
glantau
parents:
diff changeset
14 *
986e461dc072 Initial revision
glantau
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License
986e461dc072 Initial revision
glantau
parents:
diff changeset
16 * along with this program; if not, write to the Free Software
986e461dc072 Initial revision
glantau
parents:
diff changeset
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
986e461dc072 Initial revision
glantau
parents:
diff changeset
18 */
64
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
19 #include "avcodec.h"
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
20 #include <math.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
21
986e461dc072 Initial revision
glantau
parents:
diff changeset
22 typedef struct {
986e461dc072 Initial revision
glantau
parents:
diff changeset
23 /* fractional resampling */
986e461dc072 Initial revision
glantau
parents:
diff changeset
24 UINT32 incr; /* fractional increment */
986e461dc072 Initial revision
glantau
parents:
diff changeset
25 UINT32 frac;
986e461dc072 Initial revision
glantau
parents:
diff changeset
26 int last_sample;
986e461dc072 Initial revision
glantau
parents:
diff changeset
27 /* integer down sample */
986e461dc072 Initial revision
glantau
parents:
diff changeset
28 int iratio; /* integer divison ratio */
986e461dc072 Initial revision
glantau
parents:
diff changeset
29 int icount, isum;
986e461dc072 Initial revision
glantau
parents:
diff changeset
30 int inv;
986e461dc072 Initial revision
glantau
parents:
diff changeset
31 } ReSampleChannelContext;
986e461dc072 Initial revision
glantau
parents:
diff changeset
32
986e461dc072 Initial revision
glantau
parents:
diff changeset
33 struct ReSampleContext {
986e461dc072 Initial revision
glantau
parents:
diff changeset
34 ReSampleChannelContext channel_ctx[2];
986e461dc072 Initial revision
glantau
parents:
diff changeset
35 float ratio;
986e461dc072 Initial revision
glantau
parents:
diff changeset
36 /* channel convert */
986e461dc072 Initial revision
glantau
parents:
diff changeset
37 int input_channels, output_channels, filter_channels;
986e461dc072 Initial revision
glantau
parents:
diff changeset
38 };
986e461dc072 Initial revision
glantau
parents:
diff changeset
39
986e461dc072 Initial revision
glantau
parents:
diff changeset
40
986e461dc072 Initial revision
glantau
parents:
diff changeset
41 #define FRAC_BITS 16
986e461dc072 Initial revision
glantau
parents:
diff changeset
42 #define FRAC (1 << FRAC_BITS)
986e461dc072 Initial revision
glantau
parents:
diff changeset
43
986e461dc072 Initial revision
glantau
parents:
diff changeset
44 static void init_mono_resample(ReSampleChannelContext *s, float ratio)
986e461dc072 Initial revision
glantau
parents:
diff changeset
45 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
46 ratio = 1.0 / ratio;
986e461dc072 Initial revision
glantau
parents:
diff changeset
47 s->iratio = (int)floor(ratio);
986e461dc072 Initial revision
glantau
parents:
diff changeset
48 if (s->iratio == 0)
986e461dc072 Initial revision
glantau
parents:
diff changeset
49 s->iratio = 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
50 s->incr = (int)((ratio / s->iratio) * FRAC);
986e461dc072 Initial revision
glantau
parents:
diff changeset
51 s->frac = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
52 s->last_sample = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
53 s->icount = s->iratio;
986e461dc072 Initial revision
glantau
parents:
diff changeset
54 s->isum = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
55 s->inv = (FRAC / s->iratio);
986e461dc072 Initial revision
glantau
parents:
diff changeset
56 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
57
986e461dc072 Initial revision
glantau
parents:
diff changeset
58 /* fractional audio resampling */
986e461dc072 Initial revision
glantau
parents:
diff changeset
59 static int fractional_resample(ReSampleChannelContext *s, short *output, short *input, int nb_samples)
986e461dc072 Initial revision
glantau
parents:
diff changeset
60 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
61 unsigned int frac, incr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
62 int l0, l1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
63 short *q, *p, *pend;
986e461dc072 Initial revision
glantau
parents:
diff changeset
64
986e461dc072 Initial revision
glantau
parents:
diff changeset
65 l0 = s->last_sample;
986e461dc072 Initial revision
glantau
parents:
diff changeset
66 incr = s->incr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
67 frac = s->frac;
986e461dc072 Initial revision
glantau
parents:
diff changeset
68
986e461dc072 Initial revision
glantau
parents:
diff changeset
69 p = input;
986e461dc072 Initial revision
glantau
parents:
diff changeset
70 pend = input + nb_samples;
986e461dc072 Initial revision
glantau
parents:
diff changeset
71 q = output;
986e461dc072 Initial revision
glantau
parents:
diff changeset
72
986e461dc072 Initial revision
glantau
parents:
diff changeset
73 l1 = *p++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
74 for(;;) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
75 /* interpolate */
986e461dc072 Initial revision
glantau
parents:
diff changeset
76 *q++ = (l0 * (FRAC - frac) + l1 * frac) >> FRAC_BITS;
986e461dc072 Initial revision
glantau
parents:
diff changeset
77 frac = frac + s->incr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
78 while (frac >= FRAC) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
79 if (p >= pend)
986e461dc072 Initial revision
glantau
parents:
diff changeset
80 goto the_end;
986e461dc072 Initial revision
glantau
parents:
diff changeset
81 frac -= FRAC;
986e461dc072 Initial revision
glantau
parents:
diff changeset
82 l0 = l1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
83 l1 = *p++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
84 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
85 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
86 the_end:
986e461dc072 Initial revision
glantau
parents:
diff changeset
87 s->last_sample = l1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
88 s->frac = frac;
986e461dc072 Initial revision
glantau
parents:
diff changeset
89 return q - output;
986e461dc072 Initial revision
glantau
parents:
diff changeset
90 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
91
986e461dc072 Initial revision
glantau
parents:
diff changeset
92 static int integer_downsample(ReSampleChannelContext *s, short *output, short *input, int nb_samples)
986e461dc072 Initial revision
glantau
parents:
diff changeset
93 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
94 short *q, *p, *pend;
986e461dc072 Initial revision
glantau
parents:
diff changeset
95 int c, sum;
986e461dc072 Initial revision
glantau
parents:
diff changeset
96
986e461dc072 Initial revision
glantau
parents:
diff changeset
97 p = input;
986e461dc072 Initial revision
glantau
parents:
diff changeset
98 pend = input + nb_samples;
986e461dc072 Initial revision
glantau
parents:
diff changeset
99 q = output;
986e461dc072 Initial revision
glantau
parents:
diff changeset
100
986e461dc072 Initial revision
glantau
parents:
diff changeset
101 c = s->icount;
986e461dc072 Initial revision
glantau
parents:
diff changeset
102 sum = s->isum;
986e461dc072 Initial revision
glantau
parents:
diff changeset
103
986e461dc072 Initial revision
glantau
parents:
diff changeset
104 for(;;) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
105 sum += *p++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
106 if (--c == 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
107 *q++ = (sum * s->inv) >> FRAC_BITS;
986e461dc072 Initial revision
glantau
parents:
diff changeset
108 c = s->iratio;
986e461dc072 Initial revision
glantau
parents:
diff changeset
109 sum = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
110 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
111 if (p >= pend)
986e461dc072 Initial revision
glantau
parents:
diff changeset
112 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
113 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
114 s->isum = sum;
986e461dc072 Initial revision
glantau
parents:
diff changeset
115 s->icount = c;
986e461dc072 Initial revision
glantau
parents:
diff changeset
116 return q - output;
986e461dc072 Initial revision
glantau
parents:
diff changeset
117 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
118
986e461dc072 Initial revision
glantau
parents:
diff changeset
119 /* n1: number of samples */
986e461dc072 Initial revision
glantau
parents:
diff changeset
120 static void stereo_to_mono(short *output, short *input, int n1)
986e461dc072 Initial revision
glantau
parents:
diff changeset
121 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
122 short *p, *q;
986e461dc072 Initial revision
glantau
parents:
diff changeset
123 int n = n1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
124
986e461dc072 Initial revision
glantau
parents:
diff changeset
125 p = input;
986e461dc072 Initial revision
glantau
parents:
diff changeset
126 q = output;
986e461dc072 Initial revision
glantau
parents:
diff changeset
127 while (n >= 4) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
128 q[0] = (p[0] + p[1]) >> 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
129 q[1] = (p[2] + p[3]) >> 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
130 q[2] = (p[4] + p[5]) >> 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
131 q[3] = (p[6] + p[7]) >> 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
132 q += 4;
986e461dc072 Initial revision
glantau
parents:
diff changeset
133 p += 8;
986e461dc072 Initial revision
glantau
parents:
diff changeset
134 n -= 4;
986e461dc072 Initial revision
glantau
parents:
diff changeset
135 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
136 while (n > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
137 q[0] = (p[0] + p[1]) >> 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
138 q++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
139 p += 2;
986e461dc072 Initial revision
glantau
parents:
diff changeset
140 n--;
986e461dc072 Initial revision
glantau
parents:
diff changeset
141 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
142 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
143
986e461dc072 Initial revision
glantau
parents:
diff changeset
144 /* n1: number of samples */
986e461dc072 Initial revision
glantau
parents:
diff changeset
145 static void mono_to_stereo(short *output, short *input, int n1)
986e461dc072 Initial revision
glantau
parents:
diff changeset
146 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
147 short *p, *q;
986e461dc072 Initial revision
glantau
parents:
diff changeset
148 int n = n1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
149 int v;
986e461dc072 Initial revision
glantau
parents:
diff changeset
150
986e461dc072 Initial revision
glantau
parents:
diff changeset
151 p = input;
986e461dc072 Initial revision
glantau
parents:
diff changeset
152 q = output;
986e461dc072 Initial revision
glantau
parents:
diff changeset
153 while (n >= 4) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
154 v = p[0]; q[0] = v; q[1] = v;
986e461dc072 Initial revision
glantau
parents:
diff changeset
155 v = p[1]; q[2] = v; q[3] = v;
986e461dc072 Initial revision
glantau
parents:
diff changeset
156 v = p[2]; q[4] = v; q[5] = v;
986e461dc072 Initial revision
glantau
parents:
diff changeset
157 v = p[3]; q[6] = v; q[7] = v;
986e461dc072 Initial revision
glantau
parents:
diff changeset
158 q += 8;
986e461dc072 Initial revision
glantau
parents:
diff changeset
159 p += 4;
986e461dc072 Initial revision
glantau
parents:
diff changeset
160 n -= 4;
986e461dc072 Initial revision
glantau
parents:
diff changeset
161 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
162 while (n > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
163 v = p[0]; q[0] = v; q[1] = v;
986e461dc072 Initial revision
glantau
parents:
diff changeset
164 q += 2;
986e461dc072 Initial revision
glantau
parents:
diff changeset
165 p += 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
166 n--;
986e461dc072 Initial revision
glantau
parents:
diff changeset
167 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
168 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
169
986e461dc072 Initial revision
glantau
parents:
diff changeset
170 /* XXX: should use more abstract 'N' channels system */
986e461dc072 Initial revision
glantau
parents:
diff changeset
171 static void stereo_split(short *output1, short *output2, short *input, int n)
986e461dc072 Initial revision
glantau
parents:
diff changeset
172 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
173 int i;
986e461dc072 Initial revision
glantau
parents:
diff changeset
174
986e461dc072 Initial revision
glantau
parents:
diff changeset
175 for(i=0;i<n;i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
176 *output1++ = *input++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
177 *output2++ = *input++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
178 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
179 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
180
986e461dc072 Initial revision
glantau
parents:
diff changeset
181 static void stereo_mux(short *output, short *input1, short *input2, int n)
986e461dc072 Initial revision
glantau
parents:
diff changeset
182 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
183 int i;
986e461dc072 Initial revision
glantau
parents:
diff changeset
184
986e461dc072 Initial revision
glantau
parents:
diff changeset
185 for(i=0;i<n;i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
186 *output++ = *input1++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
187 *output++ = *input2++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
188 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
189 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
190
986e461dc072 Initial revision
glantau
parents:
diff changeset
191 static int mono_resample(ReSampleChannelContext *s, short *output, short *input, int nb_samples)
986e461dc072 Initial revision
glantau
parents:
diff changeset
192 {
64
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
193 short *buf1;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
194 short *buftmp;
986e461dc072 Initial revision
glantau
parents:
diff changeset
195
64
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
196 buf1= (short*) malloc( nb_samples * sizeof(short) );
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
197
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
198 /* first downsample by an integer factor with averaging filter */
986e461dc072 Initial revision
glantau
parents:
diff changeset
199 if (s->iratio > 1) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
200 buftmp = buf1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
201 nb_samples = integer_downsample(s, buftmp, input, nb_samples);
986e461dc072 Initial revision
glantau
parents:
diff changeset
202 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
203 buftmp = input;
986e461dc072 Initial revision
glantau
parents:
diff changeset
204 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
205
986e461dc072 Initial revision
glantau
parents:
diff changeset
206 /* then do a fractional resampling with linear interpolation */
986e461dc072 Initial revision
glantau
parents:
diff changeset
207 if (s->incr != FRAC) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
208 nb_samples = fractional_resample(s, output, buftmp, nb_samples);
986e461dc072 Initial revision
glantau
parents:
diff changeset
209 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
210 memcpy(output, buftmp, nb_samples * sizeof(short));
986e461dc072 Initial revision
glantau
parents:
diff changeset
211 }
64
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
212 free(buf1);
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
213 return nb_samples;
986e461dc072 Initial revision
glantau
parents:
diff changeset
214 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
215
986e461dc072 Initial revision
glantau
parents:
diff changeset
216 ReSampleContext *audio_resample_init(int output_channels, int input_channels,
986e461dc072 Initial revision
glantau
parents:
diff changeset
217 int output_rate, int input_rate)
986e461dc072 Initial revision
glantau
parents:
diff changeset
218 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
219 ReSampleContext *s;
986e461dc072 Initial revision
glantau
parents:
diff changeset
220 int i;
986e461dc072 Initial revision
glantau
parents:
diff changeset
221
986e461dc072 Initial revision
glantau
parents:
diff changeset
222 if (output_channels > 2 || input_channels > 2)
986e461dc072 Initial revision
glantau
parents:
diff changeset
223 return NULL;
986e461dc072 Initial revision
glantau
parents:
diff changeset
224
986e461dc072 Initial revision
glantau
parents:
diff changeset
225 s = av_mallocz(sizeof(ReSampleContext));
986e461dc072 Initial revision
glantau
parents:
diff changeset
226 if (!s)
986e461dc072 Initial revision
glantau
parents:
diff changeset
227 return NULL;
986e461dc072 Initial revision
glantau
parents:
diff changeset
228
986e461dc072 Initial revision
glantau
parents:
diff changeset
229 s->ratio = (float)output_rate / (float)input_rate;
986e461dc072 Initial revision
glantau
parents:
diff changeset
230
986e461dc072 Initial revision
glantau
parents:
diff changeset
231 s->input_channels = input_channels;
986e461dc072 Initial revision
glantau
parents:
diff changeset
232 s->output_channels = output_channels;
986e461dc072 Initial revision
glantau
parents:
diff changeset
233
986e461dc072 Initial revision
glantau
parents:
diff changeset
234 s->filter_channels = s->input_channels;
986e461dc072 Initial revision
glantau
parents:
diff changeset
235 if (s->output_channels < s->filter_channels)
986e461dc072 Initial revision
glantau
parents:
diff changeset
236 s->filter_channels = s->output_channels;
986e461dc072 Initial revision
glantau
parents:
diff changeset
237
986e461dc072 Initial revision
glantau
parents:
diff changeset
238 for(i=0;i<s->filter_channels;i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
239 init_mono_resample(&s->channel_ctx[i], s->ratio);
986e461dc072 Initial revision
glantau
parents:
diff changeset
240 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
241 return s;
986e461dc072 Initial revision
glantau
parents:
diff changeset
242 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
243
986e461dc072 Initial revision
glantau
parents:
diff changeset
244 /* resample audio. 'nb_samples' is the number of input samples */
986e461dc072 Initial revision
glantau
parents:
diff changeset
245 /* XXX: optimize it ! */
986e461dc072 Initial revision
glantau
parents:
diff changeset
246 /* XXX: do it with polyphase filters, since the quality here is
986e461dc072 Initial revision
glantau
parents:
diff changeset
247 HORRIBLE. Return the number of samples available in output */
986e461dc072 Initial revision
glantau
parents:
diff changeset
248 int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples)
986e461dc072 Initial revision
glantau
parents:
diff changeset
249 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
250 int i, nb_samples1;
64
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
251 short *bufin[2];
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
252 short *bufout[2];
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
253 short *buftmp2[2], *buftmp3[2];
64
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
254 int lenout;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
255
986e461dc072 Initial revision
glantau
parents:
diff changeset
256 if (s->input_channels == s->output_channels && s->ratio == 1.0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
257 /* nothing to do */
986e461dc072 Initial revision
glantau
parents:
diff changeset
258 memcpy(output, input, nb_samples * s->input_channels * sizeof(short));
986e461dc072 Initial revision
glantau
parents:
diff changeset
259 return nb_samples;
986e461dc072 Initial revision
glantau
parents:
diff changeset
260 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
261
64
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
262 /* XXX: move those malloc to resample init code */
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
263 bufin[0]= (short*) malloc( nb_samples * sizeof(short) );
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
264 bufin[1]= (short*) malloc( nb_samples * sizeof(short) );
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
265
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
266 /* make some zoom to avoid round pb */
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
267 lenout= (int)(nb_samples * s->ratio) + 16;
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
268 bufout[0]= (short*) malloc( lenout * sizeof(short) );
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
269 bufout[1]= (short*) malloc( lenout * sizeof(short) );
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
270
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
271 if (s->input_channels == 2 &&
986e461dc072 Initial revision
glantau
parents:
diff changeset
272 s->output_channels == 1) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
273 buftmp2[0] = bufin[0];
986e461dc072 Initial revision
glantau
parents:
diff changeset
274 buftmp3[0] = output;
986e461dc072 Initial revision
glantau
parents:
diff changeset
275 stereo_to_mono(buftmp2[0], input, nb_samples);
986e461dc072 Initial revision
glantau
parents:
diff changeset
276 } else if (s->output_channels == 2 && s->input_channels == 1) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
277 buftmp2[0] = input;
986e461dc072 Initial revision
glantau
parents:
diff changeset
278 buftmp3[0] = bufout[0];
986e461dc072 Initial revision
glantau
parents:
diff changeset
279 } else if (s->output_channels == 2) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
280 buftmp2[0] = bufin[0];
986e461dc072 Initial revision
glantau
parents:
diff changeset
281 buftmp2[1] = bufin[1];
986e461dc072 Initial revision
glantau
parents:
diff changeset
282 buftmp3[0] = bufout[0];
986e461dc072 Initial revision
glantau
parents:
diff changeset
283 buftmp3[1] = bufout[1];
986e461dc072 Initial revision
glantau
parents:
diff changeset
284 stereo_split(buftmp2[0], buftmp2[1], input, nb_samples);
986e461dc072 Initial revision
glantau
parents:
diff changeset
285 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
286 buftmp2[0] = input;
986e461dc072 Initial revision
glantau
parents:
diff changeset
287 buftmp3[0] = output;
986e461dc072 Initial revision
glantau
parents:
diff changeset
288 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
289
986e461dc072 Initial revision
glantau
parents:
diff changeset
290 /* resample each channel */
986e461dc072 Initial revision
glantau
parents:
diff changeset
291 nb_samples1 = 0; /* avoid warning */
986e461dc072 Initial revision
glantau
parents:
diff changeset
292 for(i=0;i<s->filter_channels;i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
293 nb_samples1 = mono_resample(&s->channel_ctx[i], buftmp3[i], buftmp2[i], nb_samples);
986e461dc072 Initial revision
glantau
parents:
diff changeset
294 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
295
986e461dc072 Initial revision
glantau
parents:
diff changeset
296 if (s->output_channels == 2 && s->input_channels == 1) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
297 mono_to_stereo(output, buftmp3[0], nb_samples1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
298 } else if (s->output_channels == 2) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
299 stereo_mux(output, buftmp3[0], buftmp3[1], nb_samples1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
300 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
301
64
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
302 free(bufin[0]);
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
303 free(bufin[1]);
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
304
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
305 free(bufout[0]);
5aa6292a1660 win32 fixes
glantau
parents: 0
diff changeset
306 free(bufout[1]);
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
307 return nb_samples1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
308 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
309
986e461dc072 Initial revision
glantau
parents:
diff changeset
310 void audio_resample_close(ReSampleContext *s)
986e461dc072 Initial revision
glantau
parents:
diff changeset
311 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
312 free(s);
986e461dc072 Initial revision
glantau
parents:
diff changeset
313 }