comparison alt_audio_convert.c @ 360:c984aa6990f7

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