Mercurial > SDL_sound_CoreAudio
annotate alt_audio_convert.c @ 347:778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Thu, 23 May 2002 12:37:13 +0000 |
parents | fbbb1f25b944 |
children | c984aa6990f7 |
rev | line source |
---|---|
338 | 1 /* |
2 Extended Audio Converter for SDL (Simple DirectMedia Layer) | |
3 Copyright (C) 2002 Frank Ranostaj | |
4 Institute of Applied Physik | |
5 Johann Wolfgang Goethe-Universität | |
6 Frankfurt am Main, Germany | |
7 | |
8 This library is free software; you can redistribute it and/or | |
9 modify it under the terms of the GNU Library General Public | |
10 License as published by the Free Software Foundation; either | |
11 version 2 of the License, or (at your option) any later version. | |
12 | |
13 This library is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 Library General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU Library General Public | |
19 License along with this library; if not, write to the Free | |
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | |
22 Frank Ranostaj | |
23 ranostaj@stud.uni-frankfurt.de | |
24 | |
25 (This code blatantly abducted for SDL_sound. Thanks, Frank! --ryan.) | |
26 */ | |
27 | |
28 #include "alt_audio_convert.h" | |
29 | |
30 #include <stdlib.h> | |
31 #include <math.h> | |
32 | |
33 /*provisorisch*/ | |
34 #define AUDIO_8 (4) | |
35 #define AUDIO_16WRONG (8) | |
36 #define AUDIO_FORMAT (AUDIO_8 | AUDIO_16WRONG) | |
37 #define AUDIO_SIGN (1) | |
38 | |
39 | |
40 /*-------------------------------------------------------------------------*/ | |
41 /* this filter (Kaiser-window beta=6.8) gives a decent -80dB attentuation */ | |
42 static const int filter[_fsize/2] = { | |
43 0, 20798, 0, -6764, 0, 3863, 0, -2560, 0, 1800, 0, -1295, 0, 936, 0, | |
44 -671, | |
45 0, 474, 0, -326, 0, 217, 0, -138, 0, 83, 0, -46, 0, 23, 0, -9 | |
46 }; | |
47 | |
48 /* Mono (1 channel ) */ | |
49 #define Suffix(x) x##1 | |
50 #include "filter_templates.h" | |
51 #undef Suffix | |
52 | |
53 /* Stereo (2 channel ) */ | |
54 #define Suffix(x) x##2 | |
55 #include "filter_templates.h" | |
56 #undef Suffix | |
57 | |
58 /* !!! FIXME: Lose all the "short" vars for "Sint16", etc. */ | |
59 | |
60 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
61 int Sound_ConvertAudio( Sound_AudioCVT *Data ) |
338 | 62 { |
63 AdapterC Temp; | |
64 int i; | |
65 | |
66 /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */ | |
67 int mode = 0; | |
68 | |
69 /* Make sure there's a converter */ | |
70 if( Data == NULL ) { | |
71 SDL_SetError("No converter given"); | |
72 return(-1); | |
73 } | |
74 | |
75 /* Make sure there's data to convert */ | |
76 if( Data->buf == NULL ) { | |
77 SDL_SetError("No buffer allocated for conversion"); | |
78 return(-1); | |
79 } | |
80 | |
81 /* Set up the conversion and go! */ | |
82 Temp.buffer = (short*)Data->buf; | |
83 Temp.mode = mode; | |
84 Temp.filter = &Data->filter; | |
85 | |
86 Data->len_cvt = Data->len; | |
87 for( i = 0; Data->adapter[i] != NULL; i++ ) | |
88 Data->len_cvt = (*Data->adapter[i])( Temp, Data->len_cvt); | |
89 | |
90 return(0); | |
91 } | |
92 | |
93 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
94 static int expand8BitTo16Bit( AdapterC Data, int length ) |
338 | 95 { |
96 int i; | |
97 char* inp = (char*)Data.buffer-1; | |
98 short* buffer = Data.buffer-1; | |
99 for( i = length; i; i-- ) | |
100 buffer[i] = inp[i]<<8; | |
101 return length*2; | |
102 } | |
103 | |
104 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
105 static int swapBytes( AdapterC Data, int length ) |
338 | 106 { |
107 int i; | |
108 unsigned short a,b; | |
109 short* buffer = Data.buffer; | |
110 for( i = 0; i < length; i++ ) | |
111 { | |
112 a = b = buffer[i]; | |
113 a <<= 8; | |
114 b >>= 8; | |
115 buffer[i] = a | b; | |
116 } | |
117 return length; | |
118 } | |
119 | |
120 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
121 static int cut16BitTo8Bit( AdapterC Data, int length ) |
338 | 122 { |
123 int i; | |
124 short* inp = Data.buffer-1; | |
125 char* buffer = (char*)Data.buffer-1; | |
126 for( i = 0; i < length; i++ ) | |
127 buffer[i] = inp[i]>>8; | |
128 return length/2; | |
129 } | |
130 | |
131 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
132 static int changeSigned( AdapterC Data, int length ) |
338 | 133 { |
134 int i; | |
135 short* buffer = Data.buffer; | |
136 for( i = 0; i < length; i++ ) | |
137 buffer[i] ^= 0x8000; | |
138 return length; | |
139 } | |
140 | |
141 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
142 static int convertStereoToMono( AdapterC Data, int length ) |
338 | 143 { |
144 int i; | |
145 short* buffer = Data.buffer; | |
146 | |
147 /* | |
148 * !!! FIXME: Can we avoid the division in this loop and just keep | |
149 * !!! FIXME: a second index variable? --ryan. | |
150 */ | |
151 for( i = 0; i < length; i+=2 ) | |
152 buffer[i/2] = ((int)buffer[i] + buffer[i+1] ) >> 1; | |
153 return length/2; | |
154 } | |
155 | |
156 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
157 static int convertMonoToStereo( AdapterC Data, int length ) |
338 | 158 { |
159 int i; | |
347
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
160 short* buffer = Data.buffer-1; |
338 | 161 length *= 2; |
162 | |
163 /* | |
164 * !!! FIXME: Can we avoid the division in this loop and just keep | |
165 * !!! FIXME: a second index variable? --ryan. | |
166 */ | |
167 for( i = length; i; i-=2 ) | |
347
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
168 buffer[i] = buffer [i-1] = buffer[i/2]; |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
169 return length; |
338 | 170 } |
171 | |
172 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
173 static int minus5dB( AdapterC Data, int length ) |
338 | 174 { |
175 int i; | |
176 short* buffer = Data.buffer; | |
177 for(i = length; i >= 0; i--) | |
178 buffer[i]= 38084 * buffer[i] >> 16; | |
179 return length; | |
180 } | |
181 | |
182 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
183 static int doubleRateStereo( AdapterC Data, int length ) |
338 | 184 { |
185 _doubleRate2( Data.buffer, Data.mode, length/2 ); | |
186 return 2*_doubleRate2( Data.buffer+1, Data.mode, length/2 ); | |
187 } | |
188 | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
189 static int doubleRateMono( AdapterC Data, int length ) |
338 | 190 { |
191 return _doubleRate1( Data.buffer, Data.mode, length ); | |
192 } | |
193 | |
194 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
195 static int halfRateStereo( AdapterC Data, int length ) |
338 | 196 { |
197 _halfRate2( Data.buffer, Data.mode, length/2 ); | |
198 return 2*_halfRate2( Data.buffer+1, Data.mode, length/2 ); | |
199 } | |
200 | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
201 static int halfRateMono( AdapterC Data, int length ) |
338 | 202 { |
203 return _halfRate2( Data.buffer, Data.mode, length ); | |
204 } | |
205 | |
206 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
207 static int varRateStereo( AdapterC Data, int length ) |
338 | 208 { |
209 _varRate2( Data.buffer, Data.mode, Data.filter, length/2 ); | |
210 return 2*_varRate2( Data.buffer+1, Data.mode, Data.filter, length/2 ); | |
211 } | |
212 | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
213 static int varRateMono( AdapterC Data, int length ) |
338 | 214 { |
215 return _varRate1( Data.buffer, Data.mode, Data.filter, length ); | |
216 } | |
217 | |
218 /*-------------------------------------------------------------------------*/ | |
219 typedef struct{ | |
220 short denominator; | |
221 short numerator; | |
222 } Fraction; | |
223 | |
224 /*-------------------------------------------------------------------------*/ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
225 static Fraction findFraction( float Value ) |
338 | 226 { |
227 /* gives a maximal error of 3% and typical less than 0.2% */ | |
228 const char frac[96]={ | |
229 1, 2, -1, /* /1 */ | |
230 1, 3, -1, /* /2 */ | |
231 2, 4, 5, -1, /* /3 */ | |
232 3, 5, 7, -1, /* /4 */ | |
233 3, 4, 6, 7, 8, 9, -1, /* /5 */ | |
234 5, 7, 11, -1, /* /6 */ | |
235 4, 5, 6, 8, 9, 10, 11, 12, 13, -1, /* /7 */ | |
236 5, 7, 9, 11, 13, 15, -1, /* /8 */ | |
237 5, 7, 8, 10, 11, 13, 14, 16, -1, /* /9 */ | |
238 7, 9, 11, 13, -1, /* /10 */ | |
239 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, -1, /* /11 */ | |
240 7, 11, 13, -1, /* /12 */ | |
241 7, 8, 9, 10, 11, 12, 14, 15, 16, -1, /* /13 */ | |
242 9, 11, 13, 15, -1, /* /14 */ | |
243 8, 11, 13, 14, 16, -1, /* /15 */ | |
244 9, 11, 13, 15 }; /* /16 */ | |
245 | |
246 | |
247 Fraction Result = {0,0}; | |
248 int n,num,den=2; | |
249 | |
250 float RelErr, BestErr = 0; | |
251 if( Value < 31/64. || Value > 64/31. ) return Result; | |
252 | |
253 for( n = 0; n < sizeof(frac); num=frac[++n] ) | |
254 { | |
255 if( num < 0 ) den++; | |
256 RelErr = Value * num / den; | |
257 RelErr = ( RelErr < (1/RelErr) ? RelErr : 1/RelErr ); | |
258 if( RelErr > BestErr ) | |
259 { | |
260 BestErr = RelErr; | |
261 Result.denominator = den; | |
262 Result.numerator = num; | |
263 } | |
264 } | |
265 return Result; | |
266 } | |
267 | |
268 | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
269 static float sinc( float x ) |
338 | 270 { |
271 if( x > -1e-24 && x < 1e-24 ) return 1.; | |
272 else return sin(x)/x; | |
273 } | |
274 | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
275 static void calculateVarFilter( short* dst, float Ratio, float phase, |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
276 float scale ) |
338 | 277 { |
278 const unsigned short KaiserWindow7[]= { | |
279 22930, 16292, 14648, 14288, 14470, 14945, 15608, 16404, | |
280 17304, 18289, 19347, 20467, 21644, 22872, 24145, 25460, | |
281 26812, 28198, 29612, 31052, 32513, 33991, 35482, 36983, | |
282 38487, 39993, 41494, 42986, 44466, 45928, 47368, 48782, | |
283 50165, 51513, 52821, 54086, 55302, 56466, 57575, 58624, | |
284 59610, 60529, 61379, 62156, 62858, 63483, 64027, 64490, | |
285 64870, 65165, 65375, 65498, 65535, 65484, 65347, 65124, | |
286 64815, 64422, 63946, 63389, 62753, 62039, 61251, 60391 }; | |
287 int i; | |
288 float w; | |
289 const float fg = -.018 + .5 / Ratio; | |
290 const float omega = 2 * M_PI * fg; | |
291 phase -= 63; | |
292 for( i = 0; i < 64; i++) | |
293 { | |
294 w = scale * ( KaiserWindow7[i] * ( i + 1 )); | |
295 dst[i] = w * sinc( omega * (i+phase) ); | |
296 dst[127-i] = w * sinc( omega * (127-i+phase) ); | |
297 } | |
298 } | |
299 | |
300 typedef struct{ | |
301 float scale; | |
302 int incr; | |
303 } VarFilterMode; | |
304 | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
305 static const VarFilterMode Up = { 0.0211952, 0 }; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
306 static const VarFilterMode Down = { 0.0364733, 2 }; |
338 | 307 |
308 | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
309 static void setupVarFilter( VarFilter* filter, |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
310 float Ratio, VarFilterMode Direction ) |
338 | 311 { |
312 int i,n,d; | |
313 Fraction IRatio; | |
314 float phase; | |
315 IRatio = findFraction( Ratio ); | |
316 | |
317 if ( (1/Ratio) < Ratio ) | |
318 Ratio = 1/Ratio; | |
319 | |
320 n = IRatio.numerator; | |
321 d = IRatio.denominator; | |
322 filter->pos_mod = n; | |
323 | |
324 for( i = 0; i < d; i++ ) | |
325 { | |
326 if( phase >= n ) | |
327 { | |
328 phase -= d; | |
329 filter->incr[i] = Direction.incr; | |
330 } | |
331 else | |
332 filter->incr[i] = 1; | |
333 | |
334 calculateVarFilter( filter->c[i], Ratio, phase/(float)n, | |
335 Direction.scale ); | |
336 phase += d; | |
337 } | |
338 } | |
339 | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
340 static int createRateConverter( Sound_AudioCVT *Data, int filter_index, |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
341 int SrcRate, int DestRate, int Channel ) |
338 | 342 { |
343 int VarPos = 0; | |
344 int Mono = 2 - Channel; | |
345 float Ratio = DestRate; | |
346 if( SrcRate < 1 || SrcRate > 1<<18 || | |
347 DestRate < 1 || DestRate > 1<<18 ) return -1; | |
348 if( SrcRate == DestRate ) return filter_index; | |
349 Ratio /= SrcRate; | |
350 | |
351 if( Ratio > 1.0) | |
352 VarPos = filter_index++; | |
353 else | |
347
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
354 { |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
355 fprintf (stderr, "Filter: minus5dB\n"); |
338 | 356 Data->adapter[filter_index++] = minus5dB; |
347
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
357 } |
338 | 358 |
359 while( Ratio > 64.0/31.0) | |
360 { | |
347
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
361 fprintf (stderr, "Filter: %s\n", |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
362 Mono ? "doubleRateMono" : "doubleRateStereo"); |
338 | 363 Data->adapter[filter_index++] = |
364 Mono ? doubleRateMono : doubleRateStereo; | |
365 Ratio /= 2; | |
366 Data->len_mult *= 2; | |
367 Data->add *= 2; | |
368 Data->add += _fsize; | |
369 } | |
370 | |
371 while( Ratio < 31.0/64.0 ) | |
372 { | |
347
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
373 fprintf (stderr, "Filter: %s\n", |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
374 Mono ? "halfRateMono" : "halfRateStereo"); |
338 | 375 Data->adapter[filter_index++] = |
376 Mono ? halfRateMono : halfRateStereo; | |
377 Ratio *= 2; | |
378 } | |
379 | |
380 if( Ratio > 1.0 ) | |
381 { | |
347
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
382 fprintf (stderr, "Filter: %s\n", |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
383 Mono ? "varRateMono" : "varRateStereo"); |
338 | 384 setupVarFilter( &Data->filter, Ratio, Up ); |
385 Data->adapter[VarPos] = | |
386 Mono ? varRateMono : varRateStereo; | |
387 Data->len_mult *= 2; | |
388 Data->add *= 2; | |
389 Data->add += _fsize; | |
390 } | |
391 else | |
392 { | |
347
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
393 fprintf (stderr, "Filter: %s\n", |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
394 Mono ? "varRateMono" : "varRateStereo"); |
338 | 395 setupVarFilter( &Data->filter, Ratio, Down ); |
396 Data->adapter[filter_index++] = | |
397 Mono ? varRateMono : varRateStereo; | |
398 } | |
347
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
399 return filter_index; |
338 | 400 } |
401 | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
402 static int BuildAudioCVT(Sound_AudioCVT *Data, |
338 | 403 Uint16 src_format, Uint8 src_channels, int src_rate, |
404 Uint16 dst_format, Uint8 dst_channels, int dst_rate) | |
405 { | |
406 int filter_index = 0; | |
407 | |
408 if( Data == NULL ) return -1; | |
409 Data->len_mult = 1.0; | |
410 Data->add = 0; | |
411 | |
412 /* Check channels */ | |
413 if( src_channels < 1 || src_channels > 2 || | |
414 dst_channels < 1 || dst_channels > 2 ) goto error_exit; | |
415 | |
416 /* First filter: Size/Endian conversion */ | |
417 switch( src_format & AUDIO_FORMAT) | |
418 { | |
419 case AUDIO_8: | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
420 fprintf (stderr, "Filter: expand8BitTo16Bit\n"); |
338 | 421 Data->adapter[filter_index++] = expand8BitTo16Bit; |
422 Data->len_mult *= 2; | |
423 break; | |
424 case AUDIO_16WRONG: | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
425 fprintf (stderr, "Filter: swapBytes\n"); |
338 | 426 Data->adapter[filter_index++] = swapBytes; |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
427 break; |
338 | 428 } |
429 | |
430 /* Second adapter: Sign conversion -- unsigned/signed */ | |
431 if( src_format & AUDIO_SIGN ) | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
432 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
433 fprintf (stderr, "Filter: changeSigned\n"); |
338 | 434 Data->adapter[filter_index++] = changeSigned; |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
435 } |
338 | 436 |
437 /* Third adapter: Stereo->Mono conversion */ | |
438 if( src_channels == 2 && dst_channels == 1 ) | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
439 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
440 fprintf (stderr, "convertStereoToMono\n"); |
338 | 441 Data->adapter[filter_index++] = convertStereoToMono; |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
442 } |
338 | 443 |
444 /* Do rate conversion */ | |
445 if( src_channels == 2 && dst_channels == 2 ) | |
446 filter_index = createRateConverter( Data, filter_index, | |
447 src_rate, dst_rate, 2 ); | |
448 else | |
449 filter_index = createRateConverter( Data, filter_index, | |
450 src_rate, dst_rate, 1 ); | |
451 | |
452 if( filter_index < 0 ) goto error_exit; /* propagate error */ | |
453 | |
454 /* adapter: Mono->Stereo conversion */ | |
455 if( src_channels == 1 && dst_channels == 2 ){ | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
456 fprintf (stderr, "Filter: convertMonoToStereo\n"); |
338 | 457 Data->adapter[filter_index++] = convertMonoToStereo; |
458 Data->add *= 2; | |
459 Data->len_mult *= 2; | |
460 } | |
461 | |
462 /* adapter: final Sign conversion -- unsigned/signed */ | |
463 if( dst_format & AUDIO_SIGN ) | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
464 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
465 fprintf (stderr, "Filter: changeSigned\n"); |
338 | 466 Data->adapter[filter_index++] = changeSigned; |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
467 } |
338 | 468 |
469 /* final adapter: Size/Endian conversion */ | |
470 switch( dst_format & AUDIO_FORMAT) | |
471 { | |
472 case AUDIO_8: | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
473 fprintf (stderr, "Filter: cut16BitTo8Bit\n"); |
338 | 474 Data->adapter[filter_index++] = cut16BitTo8Bit; |
475 break; | |
476 case AUDIO_16WRONG: | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
477 fprintf (stderr, "Filter: swapBytes\n"); |
338 | 478 Data->adapter[filter_index++] = swapBytes; |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
479 break; |
338 | 480 } |
481 /* Set up the filter information */ | |
482 Data->adapter[filter_index] = NULL; | |
483 Data->needed = (filter_index > 0); | |
484 return 0; | |
485 | |
486 error_exit: | |
487 Data->adapter[0] = NULL; | |
488 return -1; | |
489 } | |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
490 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
491 /* |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
492 * Frank's audio converter has its own ideas about how to represent audio |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
493 * format, so at least for a transition period we use this to glue his code |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
494 * to our's. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
495 * |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
496 * + The expand8BitTo16Bit filter will only convert to system byte order. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
497 * + The cut16BitTo8Bit filter will only convert from system byte order. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
498 * + The changeSigned filter only works on 16-bit samples, system byte order. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
499 */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
500 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
501 static char *fmt_to_str(Uint16 fmt) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
502 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
503 switch (fmt) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
504 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
505 case AUDIO_U8: return " U8"; break; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
506 case AUDIO_S8: return " S8"; break; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
507 case AUDIO_U16MSB: return "U16MSB"; break; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
508 case AUDIO_S16MSB: return "S16MSB"; break; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
509 case AUDIO_U16LSB: return "U16LSB"; break; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
510 case AUDIO_S16LSB: return "S16LSB"; break; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
511 } |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
512 return "??????"; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
513 } |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
514 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
515 #define IS_8BIT(x) ((x) & 0x0008) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
516 #define IS_16BIT(x) ((x) & 0x0010) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
517 #define ENDIAN(x) ((x) & 0x1000) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
518 #define SIGNED(x) ((x) & 0x8000) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
519 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
520 int Sound_BuildAudioCVT(Sound_AudioCVT *Data, |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
521 Uint16 src_in_format, Uint8 src_channels, int src_rate, |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
522 Uint16 dst_in_format, Uint8 dst_channels, int dst_rate) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
523 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
524 Uint16 src_format = 0; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
525 Uint16 dst_format = 0; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
526 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
527 fprintf (stderr, |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
528 "format: %s -> %s\n" |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
529 "channels: %6d -> %6d\n" |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
530 "rate: %6d -> %6d\n", |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
531 fmt_to_str (src_in_format), fmt_to_str (dst_in_format), |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
532 src_channels, dst_channels, |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
533 src_rate, dst_rate); |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
534 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
535 if ( IS_8BIT(src_in_format) && IS_16BIT(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
536 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
537 src_format |= AUDIO_8; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
538 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
539 /* |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
540 * Signedness and byte-order changes must wait until the data |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
541 * has been converted to 16-bit samples. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
542 */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
543 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
544 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
545 dst_format |= AUDIO_SIGN; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
546 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
547 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
548 if ( ENDIAN(dst_in_format) != ENDIAN(AUDIO_U16SYS) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
549 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
550 dst_format |= AUDIO_16WRONG; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
551 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
552 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
553 else if ( IS_16BIT(src_in_format) && IS_8BIT(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
554 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
555 dst_format |= AUDIO_8; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
556 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
557 /* |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
558 * Byte-order and signedness changes must be made before the data |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
559 * has been converted to 8-bit samples. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
560 */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
561 if ( ENDIAN(src_in_format) != ENDIAN(AUDIO_U16SYS) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
562 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
563 src_format |= AUDIO_16WRONG; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
564 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
565 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
566 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
567 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
568 src_format |= AUDIO_SIGN; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
569 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
570 } /* else if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
571 else if ( IS_16BIT(src_in_format) && IS_16BIT(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
572 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
573 if ( ENDIAN(src_in_format) != ENDIAN(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
574 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
575 if ( ENDIAN(src_in_format) == ENDIAN(AUDIO_U16SYS) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
576 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
577 dst_format |= AUDIO_16WRONG; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
578 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
579 /* |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
580 * The data is already is system byte order, so any |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
581 * signedness change has to be made before changing byte |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
582 * order. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
583 */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
584 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
585 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
586 src_format |= AUDIO_SIGN; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
587 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
588 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
589 else |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
590 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
591 src_format |= AUDIO_16WRONG; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
592 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
593 /* |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
594 * The data is not in system byte order, so any signedness |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
595 * change has to be made after changing byte order. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
596 */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
597 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
598 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
599 dst_format |= AUDIO_SIGN; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
600 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
601 } /* else */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
602 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
603 else if ( ENDIAN(src_in_format) != SIGNED(AUDIO_U16SYS) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
604 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
605 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
606 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
607 /* |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
608 * !!! FIXME !!! |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
609 * |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
610 * The changeSigned filter only works on system byte |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
611 * order. In this case, both source and destination is |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
612 * in opposite byte order, but the sign has to changed |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
613 * so we need to convert to system byte order, change |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
614 * sign, and then convert back to the original byte |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
615 * order again. This is not an optimal solution. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
616 */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
617 src_format |= ( AUDIO_16WRONG | AUDIO_SIGN ); |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
618 dst_format |= AUDIO_16WRONG; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
619 } /* if */ |
347
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
620 |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
621 if ( src_rate != dst_rate ) |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
622 { |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
623 /* |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
624 * !!! FIXME !!! |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
625 * |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
626 * The audio conversion filter probably only works if the |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
627 * data is in system byte order. So we need to convert to |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
628 * system byte order, and then back to original byte |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
629 * order. This is not an optimal solution. |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
630 */ |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
631 src_format |= AUDIO_16WRONG; |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
632 dst_format |= AUDIO_16WRONG; |
778cee61e1be
Mono-to-stereo fixes, more fprintf debugging output.
Ryan C. Gordon <icculus@icculus.org>
parents:
342
diff
changeset
|
633 } |
342
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
634 } /* else if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
635 else if ( SIGNED(src_in_format) != SIGNED(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
636 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
637 src_format |= AUDIO_SIGN; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
638 } /* else if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
639 } /* else if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
640 else if ( IS_8BIT(src_in_format) && IS_8BIT(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
641 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
642 /* |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
643 * !!! FIXME !!! |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
644 * |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
645 * The changeSigned filter only works on 16-bit samples, so if |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
646 * the signedness differs we have to convert from 8 to 16 bits, |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
647 * change the sign and then convert back to 8 bits again. This |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
648 * is not an optimal solution. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
649 */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
650 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
651 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
652 src_format |= ( AUDIO_8 | AUDIO_SIGN ); |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
653 dst_format |= AUDIO_8; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
654 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
655 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
656 /* |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
657 * !!! FIXME !!! |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
658 * |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
659 * The convertMonoToStereo and convertStereoToMono filters only |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
660 * work with 16-bit samples. So if those are to be applied, we |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
661 * need to convert to 16-bit samples, and then back again. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
662 */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
663 if ( src_channels != dst_channels ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
664 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
665 src_format |= AUDIO_8; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
666 dst_format |= AUDIO_8; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
667 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
668 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
669 /* |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
670 * !!! FIXME !!! |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
671 * |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
672 * The rate conversion filters almost certainly only work with |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
673 * 16-bit samples. Yadda, yadda, yadda. |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
674 */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
675 if ( src_rate != dst_rate ) |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
676 { |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
677 src_format |= AUDIO_8; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
678 dst_format |= AUDIO_8; |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
679 } /* if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
680 } /* else if */ |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
681 |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
682 return BuildAudioCVT(Data, src_format, src_channels, src_rate, |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
683 dst_format, dst_channels, dst_rate); |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
684 } |
fbbb1f25b944
Cleanups by Torbj�rn.
Ryan C. Gordon <icculus@icculus.org>
parents:
338
diff
changeset
|
685 |
338 | 686 /*-------------------------------------------------------------------------*/ |
687 |