|
Lines 15-22
Link Here
|
| 15 |
#include "audioconvert/audioconvert.h" |
15 |
#include "audioconvert/audioconvert.h" |
| 16 |
|
16 |
|
| 17 |
/* Convert rate up by multiple of 2 */ |
17 |
/* Convert rate up by multiple of 2 */ |
| 18 |
void acFreqMUL2(acAudioCVT *cvt, ALushort format) { |
18 |
void acFreqMUL2(acAudioCVT *cvt, ALushort format, ALushort channels) |
| 19 |
int i; |
19 |
{ |
|
|
20 |
int i, j; |
| 20 |
ALubyte *src, *dst; |
21 |
ALubyte *src, *dst; |
| 21 |
src = (ALubyte *) cvt->buf + cvt->len_cvt; |
22 |
src = (ALubyte *) cvt->buf + cvt->len_cvt; |
| 22 |
dst = (ALubyte *) cvt->buf + cvt->len_cvt * 2; |
23 |
dst = (ALubyte *) cvt->buf + cvt->len_cvt * 2; |
|
Lines 25-132
Link Here
|
| 25 |
case 8: |
26 |
case 8: |
| 26 |
if (format == AUDIO_U8) { |
27 |
if (format == AUDIO_U8) { |
| 27 |
ALubyte *src8 = (ALubyte*) src; |
28 |
ALubyte *src8 = (ALubyte*) src; |
| 28 |
ALubyte *dst8 = (ALubyte*) dst; |
29 |
ALubyte *dst8 = (ALubyte*) dst - channels; |
| 29 |
src8 -= 1; |
|
|
| 30 |
dst8 -= 2; |
| 31 |
/* For the first sample to be processed (last sample |
30 |
/* For the first sample to be processed (last sample |
| 32 |
in the buffer) there's no 'next' sample in the |
31 |
in the buffer) there's no 'next' sample in the |
| 33 |
buffer to interpolate against. So we use a value |
32 |
buffer to interpolate against. So we use a value |
| 34 |
extrapolated (then dampened) from the previous |
33 |
extrapolated (then dampened) from the previous |
| 35 |
sample in the buffer; this dampens (but doesn't |
34 |
sample in the buffer; this dampens (but doesn't |
| 36 |
eliminate :() the 'click' of the first sample. */ |
35 |
eliminate :() the 'click' of the first sample. */ |
| 37 |
if (cvt->len_cvt >= 2) { |
36 |
if (cvt->len_cvt >= channels*2) { |
| 38 |
int ex; /* extrapolated sample, damped */ |
37 |
for( i=channels; i; --i) { |
| 39 |
ex = src8[0] + (src8[0]-(int)src8[-1])/8; |
38 |
int ex; /* extrapolated sample, damped */ |
| 40 |
if ( ex > 255 ) |
|
|
| 41 |
ex = 255; |
| 42 |
else if ( ex < 0 ) |
| 43 |
ex = 0; |
| 44 |
dst8[0] = src8[0]; |
| 45 |
dst8[1] = ex; |
| 46 |
for ( i=cvt->len_cvt-1; i; --i ) { |
| 47 |
src8 -= 1; |
39 |
src8 -= 1; |
| 48 |
dst8 -= 2; |
40 |
dst8 -= 1; |
|
|
41 |
ex = src8[0] + (src8[0]-(int)src8[-channels])/8; |
| 42 |
if ( ex > 255 ) |
| 43 |
ex = 255; |
| 44 |
else if ( ex < 0 ) |
| 45 |
ex = 0; |
| 49 |
dst8[0] = src8[0]; |
46 |
dst8[0] = src8[0]; |
| 50 |
dst8[1] = (src8[0]+(int)src8[1])/2; |
47 |
dst8[channels] = ex; |
| 51 |
} |
48 |
} |
| 52 |
} else if (cvt->len_cvt == 1) { |
49 |
for ( i=cvt->len_cvt-channels; i; ) { |
| 53 |
dst8[0] = src8[0]; |
50 |
dst8 -= channels; |
| 54 |
dst8[1] = src8[0]; |
51 |
for( j=channels; j; --j,--i) { |
|
|
52 |
src8 -= 1; |
| 53 |
dst8 -= 1; |
| 54 |
dst8[0] = src8[0]; |
| 55 |
dst8[channels] = (src8[0]+(int)src8[channels])/2; |
| 56 |
} |
| 57 |
} |
| 58 |
} else if (cvt->len_cvt >= channels*1) { |
| 59 |
for( i=channels; i; --i) { |
| 60 |
src8 -= 1; |
| 61 |
dst8 -= 1; |
| 62 |
dst8[0] = src8[0]; |
| 63 |
dst8[channels] = src8[0]; |
| 64 |
} |
| 55 |
} |
65 |
} |
| 56 |
} else if (format == AUDIO_S8) { |
66 |
} else if (format == AUDIO_S8) { |
| 57 |
ALbyte *src8 = (ALbyte*) src; |
67 |
ALbyte *src8 = (ALbyte*) src; |
| 58 |
ALbyte *dst8 = (ALbyte*) dst; |
68 |
ALbyte *dst8 = (ALbyte*) dst - channels; |
| 59 |
src8 -= 1; |
69 |
if (cvt->len_cvt >= channels*2) { |
| 60 |
dst8 -= 2; |
70 |
for( i=channels; i; --i) { |
| 61 |
if (cvt->len_cvt >= 2) { |
71 |
int ex; /* extrapolated sample, damped */ |
| 62 |
int ex; /* extrapolated sample, damped */ |
|
|
| 63 |
ex = src8[0] + (src8[0]-(int)src8[-1])/8; |
| 64 |
if ( ex > 127 ) |
| 65 |
ex = 127; |
| 66 |
else if ( ex < -128 ) |
| 67 |
ex = -128; |
| 68 |
dst8[0] = src8[0]; |
| 69 |
dst8[1] = ex; |
| 70 |
for ( i=cvt->len_cvt-1; i; --i ) { |
| 71 |
src8 -= 1; |
72 |
src8 -= 1; |
| 72 |
dst8 -= 2; |
73 |
dst8 -= 1; |
|
|
74 |
ex = src8[0] + (src8[0]-(int)src8[-channels])/8; |
| 75 |
if ( ex > 127 ) |
| 76 |
ex = 127; |
| 77 |
else if ( ex < -128 ) |
| 78 |
ex = -128; |
| 73 |
dst8[0] = src8[0]; |
79 |
dst8[0] = src8[0]; |
| 74 |
dst8[1] = (src8[0]+(int)src8[1])/2; |
80 |
dst8[channels] = ex; |
| 75 |
} |
81 |
} |
| 76 |
} else { |
82 |
for ( i=cvt->len_cvt-channels; i; ) { |
| 77 |
dst8[0] = src8[0]; |
83 |
dst8 -= channels; |
| 78 |
dst8[1] = src8[0]; |
84 |
for( j=channels; j; --j,--i) { |
|
|
85 |
src8 -= 1; |
| 86 |
dst8 -= 1; |
| 87 |
dst8[0] = src8[0]; |
| 88 |
dst8[channels] = (src8[0]+(int)src8[channels])/2; |
| 89 |
} |
| 90 |
} |
| 91 |
} else if (cvt->len_cvt >= channels*1) { |
| 92 |
for( i=channels; i; --i) { |
| 93 |
src8 -= 1; |
| 94 |
dst8 -= 1; |
| 95 |
dst8[0] = src8[0]; |
| 96 |
dst8[channels] = src8[0]; |
| 97 |
} |
| 79 |
} |
98 |
} |
| 80 |
} |
99 |
} |
| 81 |
break; |
100 |
break; |
| 82 |
case 16: |
101 |
case 16: |
| 83 |
if (format == AUDIO_S16) { |
102 |
if (format == AUDIO_S16) { |
| 84 |
ALshort *src16 = (ALshort*) src; |
103 |
ALshort *src16 = (ALshort*) src; |
| 85 |
ALshort *dst16 = (ALshort*) dst; |
104 |
ALshort *dst16 = (ALshort*) dst - channels; |
| 86 |
src16 -= 1; |
105 |
if (cvt->len_cvt >= channels*4) { |
| 87 |
dst16 -= 2; |
106 |
for ( i=channels; i; --i ) { |
| 88 |
if (cvt->len_cvt >= 4) { |
107 |
int ex; /* extrapolated sample, damped */ |
| 89 |
int ex; /* extrapolated sample, damped */ |
|
|
| 90 |
ex = src16[0] + (src16[0]-(int)src16[-1])/8; |
| 91 |
if ( ex > 32767 ) |
| 92 |
ex = 32767; |
| 93 |
else if ( ex < -32768 ) |
| 94 |
ex = -32768; |
| 95 |
dst16[0] = src16[0]; |
| 96 |
dst16[1] = ex; |
| 97 |
for ( i=cvt->len_cvt/2-1; i; --i ) { |
| 98 |
src16 -= 1; |
108 |
src16 -= 1; |
| 99 |
dst16 -= 2; |
109 |
dst16 -= 1; |
|
|
110 |
ex = src16[0] + (src16[0]-(int)src16[-channels])/8; |
| 111 |
if ( ex > 32767 ) |
| 112 |
ex = 32767; |
| 113 |
else if ( ex < -32768 ) |
| 114 |
ex = -32768; |
| 100 |
dst16[0] = src16[0]; |
115 |
dst16[0] = src16[0]; |
| 101 |
dst16[1] = (src16[0]+(int)src16[1])/2; |
116 |
dst16[channels] = ex; |
| 102 |
} |
117 |
} |
| 103 |
} else if (cvt->len_cvt == 2) { |
118 |
for ( i=cvt->len_cvt/2-channels; i; ) { |
| 104 |
dst16[0] = src16[0]; |
119 |
dst16 -= channels; |
| 105 |
dst16[1] = src16[0]; |
120 |
for( j=channels; j; --j,--i) { |
|
|
121 |
src16 -= 1; |
| 122 |
dst16 -= 1; |
| 123 |
dst16[0] = src16[0]; |
| 124 |
dst16[channels] = (src16[0]+(int)src16[channels])/2; |
| 125 |
} |
| 126 |
} |
| 127 |
} else if (cvt->len_cvt >= channels*2) { |
| 128 |
for( i=channels; i; --i) { |
| 129 |
src16 -= 1; |
| 130 |
dst16 -= 1; |
| 131 |
dst16[0] = src16[0]; |
| 132 |
dst16[channels] = src16[0]; |
| 133 |
} |
| 106 |
} |
134 |
} |
| 107 |
} else if (format == AUDIO_U16) { |
135 |
} else if (format == AUDIO_U16) { |
| 108 |
ALushort *src16 = (ALushort*) src; |
136 |
ALushort *src16 = (ALushort*) src; |
| 109 |
ALushort *dst16 = (ALushort*) dst; |
137 |
ALushort *dst16 = (ALushort*) dst - channels; |
| 110 |
src16 -= 1; |
138 |
if (cvt->len_cvt >= channels*4) { |
| 111 |
dst16 -= 2; |
139 |
for( i=channels; i; --i) { |
| 112 |
if (cvt->len_cvt >= 4) { |
140 |
int ex; /* extrapolated sample, damped */ |
| 113 |
int ex; /* extrapolated sample, damped */ |
141 |
ex = src16[0] + (src16[0]-(int)src16[-channels])/8; |
| 114 |
ex = src16[0] + (src16[0]-(int)src16[-1])/8; |
|
|
| 115 |
if ( ex > 65535 ) |
| 116 |
ex = 65535; |
| 117 |
else if ( ex < 0 ) |
| 118 |
ex = 0; |
| 119 |
dst16[0] = src16[0]; |
| 120 |
dst16[1] = ex; |
| 121 |
for ( i=cvt->len_cvt/2-1; i; --i ) { |
| 122 |
src16 -= 1; |
142 |
src16 -= 1; |
| 123 |
dst16 -= 2; |
143 |
dst16 -= 1; |
|
|
144 |
if ( ex > 65535 ) |
| 145 |
ex = 65535; |
| 146 |
else if ( ex < 0 ) |
| 147 |
ex = 0; |
| 124 |
dst16[0] = src16[0]; |
148 |
dst16[0] = src16[0]; |
| 125 |
dst16[1] = (src16[0]+(int)src16[1])/2; |
149 |
dst16[channels] = ex; |
| 126 |
} |
150 |
} |
| 127 |
} else if (cvt->len_cvt == 2) { |
151 |
for ( i=cvt->len_cvt/2-channels; i; ) { |
| 128 |
dst16[0] = src16[0]; |
152 |
dst16 -= channels; |
| 129 |
dst16[1] = src16[0]; |
153 |
for( j=channels; j; --j,--i) { |
|
|
154 |
src16 -= 1; |
| 155 |
dst16 -= 1; |
| 156 |
dst16[0] = src16[0]; |
| 157 |
dst16[channels] = (src16[0]+(int)src16[channels])/2; |
| 158 |
} |
| 159 |
} |
| 160 |
} else if (cvt->len_cvt >= channels*2) { |
| 161 |
for( i=channels; i; --i) { |
| 162 |
src16 -= 1; |
| 163 |
dst16 -= 1; |
| 164 |
dst16[0] = src16[0]; |
| 165 |
dst16[channels] = src16[0]; |
| 166 |
} |
| 130 |
} |
167 |
} |
| 131 |
} else { |
168 |
} else { |
| 132 |
/* this is a 16-bit format that doesn't correspond |
169 |
/* this is a 16-bit format that doesn't correspond |
|
Lines 136-146
Link Here
|
| 136 |
future work. */ |
173 |
future work. */ |
| 137 |
ALushort *src16 = (ALushort*) src; |
174 |
ALushort *src16 = (ALushort*) src; |
| 138 |
ALushort *dst16 = (ALushort*) dst; |
175 |
ALushort *dst16 = (ALushort*) dst; |
| 139 |
for ( i=cvt->len_cvt/2; i; --i ) { |
176 |
for ( i=cvt->len_cvt/2; i; ) { |
| 140 |
src16 -= 1; |
177 |
dst16 -= channels; |
| 141 |
dst16 -= 2; |
178 |
for( j=channels; j; --j,--i) { |
| 142 |
dst16[0] = src16[0]; |
179 |
src16 -= 1; |
| 143 |
dst16[1] = src16[0]; |
180 |
dst16 -= 1; |
|
|
181 |
dst16[0] = src16[0]; |
| 182 |
dst16[channels] = src16[0]; |
| 183 |
} |
| 144 |
} |
184 |
} |
| 145 |
} |
185 |
} |
| 146 |
break; |
186 |
break; |
|
Lines 148-178
Link Here
|
| 148 |
cvt->len_cvt *= 2; |
188 |
cvt->len_cvt *= 2; |
| 149 |
|
189 |
|
| 150 |
if (cvt->filters[++cvt->filter_index] ) { |
190 |
if (cvt->filters[++cvt->filter_index] ) { |
| 151 |
cvt->filters[cvt->filter_index](cvt, format); |
191 |
cvt->filters[cvt->filter_index](cvt, format, channels); |
| 152 |
} |
192 |
} |
| 153 |
} |
193 |
} |
| 154 |
|
194 |
|
| 155 |
/* Convert rate down by multiple of 2 */ |
195 |
/* Convert rate down by multiple of 2 */ |
| 156 |
void acFreqDIV2(acAudioCVT *cvt, ALushort format) { |
196 |
void acFreqDIV2(acAudioCVT *cvt, ALushort format, ALushort channels) |
| 157 |
int i; |
197 |
{ |
|
|
198 |
int i, j; |
| 158 |
ALubyte *src, *dst; |
199 |
ALubyte *src, *dst; |
| 159 |
|
200 |
|
| 160 |
src = cvt->buf; |
201 |
src = cvt->buf; |
| 161 |
dst = cvt->buf; |
202 |
dst = cvt->buf; |
| 162 |
switch(format & 0xFF) { |
203 |
switch(format & 0xFF) { |
| 163 |
case 8: |
204 |
case 8: |
| 164 |
for ( i=cvt->len_cvt/2; i; --i ) { |
205 |
for ( i=cvt->len_cvt/2; i; ) { |
| 165 |
dst[0] = src[0]; |
206 |
for ( j=channels; j; --j,--i ) { |
| 166 |
src += 2; |
207 |
dst[0] = src[0]; |
| 167 |
dst += 1; |
208 |
src += 1; |
|
|
209 |
dst += 1; |
| 210 |
} |
| 211 |
src += channels; |
| 168 |
} |
212 |
} |
| 169 |
break; |
213 |
break; |
| 170 |
case 16: |
214 |
case 16: |
| 171 |
for ( i=cvt->len_cvt/4; i; --i ) { |
215 |
for ( i=cvt->len_cvt/4; i; ) { |
| 172 |
dst[0] = src[0]; |
216 |
for ( j=channels; j; --j,--i ) { |
| 173 |
dst[1] = src[1]; |
217 |
dst[0] = src[0]; |
| 174 |
src += 4; |
218 |
dst[1] = src[1]; |
| 175 |
dst += 2; |
219 |
src += 2; |
|
|
220 |
dst += 2; |
| 221 |
} |
| 222 |
src += channels*2; |
| 176 |
} |
223 |
} |
| 177 |
break; |
224 |
break; |
| 178 |
} |
225 |
} |
|
Lines 180-206
Link Here
|
| 180 |
cvt->len_cvt /= 2; |
227 |
cvt->len_cvt /= 2; |
| 181 |
|
228 |
|
| 182 |
if (cvt->filters[++cvt->filter_index] ) { |
229 |
if (cvt->filters[++cvt->filter_index] ) { |
| 183 |
cvt->filters[cvt->filter_index](cvt, format); |
230 |
cvt->filters[cvt->filter_index](cvt, format, channels); |
| 184 |
} |
231 |
} |
| 185 |
} |
232 |
} |
| 186 |
|
233 |
|
| 187 |
/* Very slow rate conversion routine */ |
234 |
/* Very slow rate conversion routine */ |
| 188 |
void acFreqSLOW(acAudioCVT *cvt, ALushort format) { |
235 |
void acFreqSLOW(acAudioCVT *cvt, ALushort format, ALushort channels) |
|
|
236 |
{ |
| 189 |
double ipos; |
237 |
double ipos; |
| 190 |
int i, clen; |
238 |
int i, j, clen; |
| 191 |
|
239 |
|
| 192 |
clen = (int) ((double)cvt->len_cvt / cvt->rate_incr); |
240 |
clen = (int) ((double)((int)cvt->len_cvt / channels) / cvt->rate_incr); |
| 193 |
if(cvt->rate_incr > 1.0) { |
241 |
if(cvt->rate_incr > 1.0) { |
| 194 |
switch(format & 0xFF) { |
242 |
switch(format & 0xFF) { |
| 195 |
case 8: { |
243 |
case 8: { |
| 196 |
ALubyte *output; |
244 |
ALubyte *output = cvt->buf; |
| 197 |
|
245 |
|
| 198 |
output = cvt->buf; |
246 |
clen *= channels; |
| 199 |
ipos = 0.0; |
247 |
ipos = 0.0; |
| 200 |
for ( i=clen; i; --i ) { |
248 |
for ( i=clen; i; ) { |
| 201 |
*output = *((ALubyte *) cvt->buf + (int)ipos); |
249 |
for ( j=0; j<channels; ++j,--i ) { |
|
|
250 |
*output=((ALubyte *)cvt->buf)[(int)ipos * channels + j]; |
| 251 |
output += 1; |
| 252 |
} |
| 202 |
ipos += cvt->rate_incr; |
253 |
ipos += cvt->rate_incr; |
| 203 |
output += 1; |
|
|
| 204 |
} |
254 |
} |
| 205 |
} |
255 |
} |
| 206 |
break; |
256 |
break; |
|
Lines 209-220
Link Here
|
| 209 |
ALushort *output; |
259 |
ALushort *output; |
| 210 |
|
260 |
|
| 211 |
clen &= ~1; |
261 |
clen &= ~1; |
|
|
262 |
clen *= channels; |
| 212 |
output = (ALushort *) cvt->buf; |
263 |
output = (ALushort *) cvt->buf; |
| 213 |
ipos = 0.0; |
264 |
ipos = 0.0; |
| 214 |
for ( i=clen/2; i; --i ) { |
265 |
for ( i=clen/2; i; ) { |
| 215 |
*output=((ALushort *)cvt->buf)[(int)ipos]; |
266 |
for ( j=0; j<channels; ++j,--i ) { |
|
|
267 |
*output=((ALushort *)cvt->buf)[(int)ipos * channels + j]; |
| 268 |
output += 1; |
| 269 |
} |
| 216 |
ipos += cvt->rate_incr; |
270 |
ipos += cvt->rate_incr; |
| 217 |
output += 1; |
|
|
| 218 |
} |
271 |
} |
| 219 |
} |
272 |
} |
| 220 |
break; |
273 |
break; |
|
Lines 229-240
Link Here
|
| 229 |
case 8: { |
282 |
case 8: { |
| 230 |
ALubyte *output; |
283 |
ALubyte *output; |
| 231 |
|
284 |
|
|
|
285 |
clen *= channels; |
| 232 |
output = (ALubyte *) cvt->buf + clen; |
286 |
output = (ALubyte *) cvt->buf + clen; |
| 233 |
ipos = (double)cvt->len_cvt; |
287 |
ipos = (double)(cvt->len_cvt / channels); |
| 234 |
for ( i=clen; i; --i ) { |
288 |
for ( i=clen; i; ) { |
|
|
289 |
for ( j=0; j<channels; ++j,--i ) { |
| 290 |
output -= 1; |
| 291 |
*output=((ALubyte *)cvt->buf)[(int)ipos * channels - j - 1]; |
| 292 |
} |
| 235 |
ipos -= cvt->rate_incr; |
293 |
ipos -= cvt->rate_incr; |
| 236 |
output -= 1; |
|
|
| 237 |
*output = *((ALubyte *) cvt->buf + (int)ipos); |
| 238 |
} |
294 |
} |
| 239 |
} |
295 |
} |
| 240 |
break; |
296 |
break; |
|
Lines 243-256
Link Here
|
| 243 |
ALushort *output; |
299 |
ALushort *output; |
| 244 |
|
300 |
|
| 245 |
clen &= ~1; |
301 |
clen &= ~1; |
|
|
302 |
clen *= channels; |
| 246 |
output = (ALushort *) cvt->buf; |
303 |
output = (ALushort *) cvt->buf; |
| 247 |
output += clen / sizeof *output; |
304 |
output += clen / sizeof *output; |
| 248 |
|
305 |
|
| 249 |
ipos = (double)cvt->len_cvt/2; |
306 |
ipos = (double)(cvt->len_cvt/2/channels); |
| 250 |
for ( i=clen/2; i; --i ) { |
307 |
for ( i=clen/2; i; ) { |
|
|
308 |
for ( j=0; j<channels; ++j,--i ) { |
| 309 |
output -= 1; |
| 310 |
*output=((ALushort *)cvt->buf)[(int)ipos * channels - j - 1]; |
| 311 |
} |
| 251 |
ipos -= cvt->rate_incr; |
312 |
ipos -= cvt->rate_incr; |
| 252 |
output -= 1; |
|
|
| 253 |
*output=((ALushort *)cvt->buf)[(int)ipos]; |
| 254 |
} |
313 |
} |
| 255 |
} |
314 |
} |
| 256 |
break; |
315 |
break; |
|
Lines 264-269
Link Here
|
| 264 |
cvt->len_cvt = clen; |
323 |
cvt->len_cvt = clen; |
| 265 |
|
324 |
|
| 266 |
if (cvt->filters[++cvt->filter_index] ) { |
325 |
if (cvt->filters[++cvt->filter_index] ) { |
| 267 |
cvt->filters[cvt->filter_index](cvt, format); |
326 |
cvt->filters[cvt->filter_index](cvt, format, channels); |
| 268 |
} |
327 |
} |
| 269 |
} |
328 |
} |