comparison alt_audio_convert.c @ 342:fbbb1f25b944

Cleanups by Torbj�rn.
author Ryan C. Gordon <icculus@icculus.org>
date Wed, 22 May 2002 09:27:54 +0000
parents 7b9a0f3f030e
children 778cee61e1be
comparison
equal deleted inserted replaced
341:3466dde3a846 342:fbbb1f25b944
56 #undef Suffix 56 #undef Suffix
57 57
58 /* !!! FIXME: Lose all the "short" vars for "Sint16", etc. */ 58 /* !!! FIXME: Lose all the "short" vars for "Sint16", etc. */
59 59
60 /*-------------------------------------------------------------------------*/ 60 /*-------------------------------------------------------------------------*/
61 int DECLSPEC Sound_ConvertAudio( Sound_AudioCVT *Data ) 61 int Sound_ConvertAudio( Sound_AudioCVT *Data )
62 { 62 {
63 AdapterC Temp; 63 AdapterC Temp;
64 int i; 64 int i;
65 65
66 /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */ 66 /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */
89 89
90 return(0); 90 return(0);
91 } 91 }
92 92
93 /*-------------------------------------------------------------------------*/ 93 /*-------------------------------------------------------------------------*/
94 int expand8BitTo16Bit( AdapterC Data, int length ) 94 static int expand8BitTo16Bit( AdapterC Data, int length )
95 { 95 {
96 int i; 96 int i;
97 char* inp = (char*)Data.buffer-1; 97 char* inp = (char*)Data.buffer-1;
98 short* buffer = Data.buffer-1; 98 short* buffer = Data.buffer-1;
99 for( i = length; i; i-- ) 99 for( i = length; i; i-- )
100 buffer[i] = inp[i]<<8; 100 buffer[i] = inp[i]<<8;
101 return length*2; 101 return length*2;
102 } 102 }
103 103
104 /*-------------------------------------------------------------------------*/ 104 /*-------------------------------------------------------------------------*/
105 int swapBytes( AdapterC Data, int length ) 105 static int swapBytes( AdapterC Data, int length )
106 { 106 {
107 int i; 107 int i;
108 unsigned short a,b; 108 unsigned short a,b;
109 short* buffer = Data.buffer; 109 short* buffer = Data.buffer;
110 for( i = 0; i < length; i++ ) 110 for( i = 0; i < length; i++ )
116 } 116 }
117 return length; 117 return length;
118 } 118 }
119 119
120 /*-------------------------------------------------------------------------*/ 120 /*-------------------------------------------------------------------------*/
121 int cut16BitTo8Bit( AdapterC Data, int length ) 121 static int cut16BitTo8Bit( AdapterC Data, int length )
122 { 122 {
123 int i; 123 int i;
124 short* inp = Data.buffer-1; 124 short* inp = Data.buffer-1;
125 char* buffer = (char*)Data.buffer-1; 125 char* buffer = (char*)Data.buffer-1;
126 for( i = 0; i < length; i++ ) 126 for( i = 0; i < length; i++ )
127 buffer[i] = inp[i]>>8; 127 buffer[i] = inp[i]>>8;
128 return length/2; 128 return length/2;
129 } 129 }
130 130
131 /*-------------------------------------------------------------------------*/ 131 /*-------------------------------------------------------------------------*/
132 int changeSigned( AdapterC Data, int length ) 132 static int changeSigned( AdapterC Data, int length )
133 { 133 {
134 int i; 134 int i;
135 short* buffer = Data.buffer; 135 short* buffer = Data.buffer;
136 for( i = 0; i < length; i++ ) 136 for( i = 0; i < length; i++ )
137 buffer[i] ^= 0x8000; 137 buffer[i] ^= 0x8000;
138 return length; 138 return length;
139 } 139 }
140 140
141 /*-------------------------------------------------------------------------*/ 141 /*-------------------------------------------------------------------------*/
142 int convertStereoToMono( AdapterC Data, int length ) 142 static int convertStereoToMono( AdapterC Data, int length )
143 { 143 {
144 int i; 144 int i;
145 short* buffer = Data.buffer; 145 short* buffer = Data.buffer;
146 146
147 /* 147 /*
152 buffer[i/2] = ((int)buffer[i] + buffer[i+1] ) >> 1; 152 buffer[i/2] = ((int)buffer[i] + buffer[i+1] ) >> 1;
153 return length/2; 153 return length/2;
154 } 154 }
155 155
156 /*-------------------------------------------------------------------------*/ 156 /*-------------------------------------------------------------------------*/
157 int convertMonoToStereo( AdapterC Data, int length ) 157 static int convertMonoToStereo( AdapterC Data, int length )
158 { 158 {
159 int i; 159 int i;
160 short* buffer = Data.buffer-2; 160 short* buffer = Data.buffer-2;
161 length *= 2; 161 length *= 2;
162 162
168 buffer[i] = buffer [i+1] = buffer[i/2]; 168 buffer[i] = buffer [i+1] = buffer[i/2];
169 return length*2; 169 return length*2;
170 } 170 }
171 171
172 /*-------------------------------------------------------------------------*/ 172 /*-------------------------------------------------------------------------*/
173 int minus5dB( AdapterC Data, int length ) 173 static int minus5dB( AdapterC Data, int length )
174 { 174 {
175 int i; 175 int i;
176 short* buffer = Data.buffer; 176 short* buffer = Data.buffer;
177 for(i = length; i >= 0; i--) 177 for(i = length; i >= 0; i--)
178 buffer[i]= 38084 * buffer[i] >> 16; 178 buffer[i]= 38084 * buffer[i] >> 16;
179 return length; 179 return length;
180 } 180 }
181 181
182 /*-------------------------------------------------------------------------*/ 182 /*-------------------------------------------------------------------------*/
183 int doubleRateStereo( AdapterC Data, int length ) 183 static int doubleRateStereo( AdapterC Data, int length )
184 { 184 {
185 _doubleRate2( Data.buffer, Data.mode, length/2 ); 185 _doubleRate2( Data.buffer, Data.mode, length/2 );
186 return 2*_doubleRate2( Data.buffer+1, Data.mode, length/2 ); 186 return 2*_doubleRate2( Data.buffer+1, Data.mode, length/2 );
187 } 187 }
188 188
189 int doubleRateMono( AdapterC Data, int length ) 189 static int doubleRateMono( AdapterC Data, int length )
190 { 190 {
191 return _doubleRate1( Data.buffer, Data.mode, length ); 191 return _doubleRate1( Data.buffer, Data.mode, length );
192 } 192 }
193 193
194 /*-------------------------------------------------------------------------*/ 194 /*-------------------------------------------------------------------------*/
195 int halfRateStereo( AdapterC Data, int length ) 195 static int halfRateStereo( AdapterC Data, int length )
196 { 196 {
197 _halfRate2( Data.buffer, Data.mode, length/2 ); 197 _halfRate2( Data.buffer, Data.mode, length/2 );
198 return 2*_halfRate2( Data.buffer+1, Data.mode, length/2 ); 198 return 2*_halfRate2( Data.buffer+1, Data.mode, length/2 );
199 } 199 }
200 200
201 int halfRateMono( AdapterC Data, int length ) 201 static int halfRateMono( AdapterC Data, int length )
202 { 202 {
203 return _halfRate2( Data.buffer, Data.mode, length ); 203 return _halfRate2( Data.buffer, Data.mode, length );
204 } 204 }
205 205
206 /*-------------------------------------------------------------------------*/ 206 /*-------------------------------------------------------------------------*/
207 int varRateStereo( AdapterC Data, int length ) 207 static int varRateStereo( AdapterC Data, int length )
208 { 208 {
209 _varRate2( Data.buffer, Data.mode, Data.filter, length/2 ); 209 _varRate2( Data.buffer, Data.mode, Data.filter, length/2 );
210 return 2*_varRate2( Data.buffer+1, Data.mode, Data.filter, length/2 ); 210 return 2*_varRate2( Data.buffer+1, Data.mode, Data.filter, length/2 );
211 } 211 }
212 212
213 int varRateMono( AdapterC Data, int length ) 213 static int varRateMono( AdapterC Data, int length )
214 { 214 {
215 return _varRate1( Data.buffer, Data.mode, Data.filter, length ); 215 return _varRate1( Data.buffer, Data.mode, Data.filter, length );
216 } 216 }
217 217
218 /*-------------------------------------------------------------------------*/ 218 /*-------------------------------------------------------------------------*/
220 short denominator; 220 short denominator;
221 short numerator; 221 short numerator;
222 } Fraction; 222 } Fraction;
223 223
224 /*-------------------------------------------------------------------------*/ 224 /*-------------------------------------------------------------------------*/
225 Fraction findFraction( float Value ) 225 static Fraction findFraction( float Value )
226 { 226 {
227 /* gives a maximal error of 3% and typical less than 0.2% */ 227 /* gives a maximal error of 3% and typical less than 0.2% */
228 const char frac[96]={ 228 const char frac[96]={
229 1, 2, -1, /* /1 */ 229 1, 2, -1, /* /1 */
230 1, 3, -1, /* /2 */ 230 1, 3, -1, /* /2 */
264 } 264 }
265 return Result; 265 return Result;
266 } 266 }
267 267
268 268
269 float sinc( float x ) 269 static float sinc( float x )
270 { 270 {
271 if( x > -1e-24 && x < 1e-24 ) return 1.; 271 if( x > -1e-24 && x < 1e-24 ) return 1.;
272 else return sin(x)/x; 272 else return sin(x)/x;
273 } 273 }
274 274
275 void calculateVarFilter( short* dst, float Ratio, float phase, float scale ) 275 static void calculateVarFilter( short* dst, float Ratio, float phase,
276 float scale )
276 { 277 {
277 const unsigned short KaiserWindow7[]= { 278 const unsigned short KaiserWindow7[]= {
278 22930, 16292, 14648, 14288, 14470, 14945, 15608, 16404, 279 22930, 16292, 14648, 14288, 14470, 14945, 15608, 16404,
279 17304, 18289, 19347, 20467, 21644, 22872, 24145, 25460, 280 17304, 18289, 19347, 20467, 21644, 22872, 24145, 25460,
280 26812, 28198, 29612, 31052, 32513, 33991, 35482, 36983, 281 26812, 28198, 29612, 31052, 32513, 33991, 35482, 36983,
299 typedef struct{ 300 typedef struct{
300 float scale; 301 float scale;
301 int incr; 302 int incr;
302 } VarFilterMode; 303 } VarFilterMode;
303 304
304 const VarFilterMode Up = { 0.0211952, 0 }; 305 static const VarFilterMode Up = { 0.0211952, 0 };
305 const VarFilterMode Down = { 0.0364733, 2 }; 306 static const VarFilterMode Down = { 0.0364733, 2 };
306 307
307 308
308 void setupVarFilter( VarFilter* filter, 309 static void setupVarFilter( VarFilter* filter,
309 float Ratio, VarFilterMode Direction ) 310 float Ratio, VarFilterMode Direction )
310 { 311 {
311 int i,n,d; 312 int i,n,d;
312 Fraction IRatio; 313 Fraction IRatio;
313 float phase; 314 float phase;
314 IRatio = findFraction( Ratio ); 315 IRatio = findFraction( Ratio );
334 Direction.scale ); 335 Direction.scale );
335 phase += d; 336 phase += d;
336 } 337 }
337 } 338 }
338 339
339 int createRateConverter( Sound_AudioCVT *Data, int filter_index, 340 static int createRateConverter( Sound_AudioCVT *Data, int filter_index,
340 int SrcRate, int DestRate, int Channel ) 341 int SrcRate, int DestRate, int Channel )
341 { 342 {
342 int VarPos = 0; 343 int VarPos = 0;
343 int Mono = 2 - Channel; 344 int Mono = 2 - Channel;
344 float Ratio = DestRate; 345 float Ratio = DestRate;
345 if( SrcRate < 1 || SrcRate > 1<<18 || 346 if( SrcRate < 1 || SrcRate > 1<<18 ||
385 Mono ? varRateMono : varRateStereo; 386 Mono ? varRateMono : varRateStereo;
386 } 387 }
387 return 0; 388 return 0;
388 } 389 }
389 390
390 int DECLSPEC Sound_BuildAudioCVT(Sound_AudioCVT *Data, 391 static int BuildAudioCVT(Sound_AudioCVT *Data,
391 Uint16 src_format, Uint8 src_channels, int src_rate, 392 Uint16 src_format, Uint8 src_channels, int src_rate,
392 Uint16 dst_format, Uint8 dst_channels, int dst_rate) 393 Uint16 dst_format, Uint8 dst_channels, int dst_rate)
393 { 394 {
394 int filter_index = 0; 395 int filter_index = 0;
395 396
403 404
404 /* First filter: Size/Endian conversion */ 405 /* First filter: Size/Endian conversion */
405 switch( src_format & AUDIO_FORMAT) 406 switch( src_format & AUDIO_FORMAT)
406 { 407 {
407 case AUDIO_8: 408 case AUDIO_8:
409 fprintf (stderr, "Filter: expand8BitTo16Bit\n");
408 Data->adapter[filter_index++] = expand8BitTo16Bit; 410 Data->adapter[filter_index++] = expand8BitTo16Bit;
409 Data->len_mult *= 2; 411 Data->len_mult *= 2;
410 break; 412 break;
411 case AUDIO_16WRONG: 413 case AUDIO_16WRONG:
414 fprintf (stderr, "Filter: swapBytes\n");
412 Data->adapter[filter_index++] = swapBytes; 415 Data->adapter[filter_index++] = swapBytes;
416 break;
413 } 417 }
414 418
415 /* Second adapter: Sign conversion -- unsigned/signed */ 419 /* Second adapter: Sign conversion -- unsigned/signed */
416 if( src_format & AUDIO_SIGN ) 420 if( src_format & AUDIO_SIGN )
421 {
422 fprintf (stderr, "Filter: changeSigned\n");
417 Data->adapter[filter_index++] = changeSigned; 423 Data->adapter[filter_index++] = changeSigned;
424 }
418 425
419 /* Third adapter: Stereo->Mono conversion */ 426 /* Third adapter: Stereo->Mono conversion */
420 if( src_channels == 2 && dst_channels == 1 ) 427 if( src_channels == 2 && dst_channels == 1 )
428 {
429 fprintf (stderr, "convertStereoToMono\n");
421 Data->adapter[filter_index++] = convertStereoToMono; 430 Data->adapter[filter_index++] = convertStereoToMono;
431 }
422 432
423 /* Do rate conversion */ 433 /* Do rate conversion */
424 if( src_channels == 2 && dst_channels == 2 ) 434 if( src_channels == 2 && dst_channels == 2 )
425 filter_index = createRateConverter( Data, filter_index, 435 filter_index = createRateConverter( Data, filter_index,
426 src_rate, dst_rate, 2 ); 436 src_rate, dst_rate, 2 );
430 440
431 if( filter_index < 0 ) goto error_exit; /* propagate error */ 441 if( filter_index < 0 ) goto error_exit; /* propagate error */
432 442
433 /* adapter: Mono->Stereo conversion */ 443 /* adapter: Mono->Stereo conversion */
434 if( src_channels == 1 && dst_channels == 2 ){ 444 if( src_channels == 1 && dst_channels == 2 ){
445 fprintf (stderr, "Filter: convertMonoToStereo\n");
435 Data->adapter[filter_index++] = convertMonoToStereo; 446 Data->adapter[filter_index++] = convertMonoToStereo;
436 Data->add *= 2; 447 Data->add *= 2;
437 Data->len_mult *= 2; 448 Data->len_mult *= 2;
438 } 449 }
439 450
440 /* adapter: final Sign conversion -- unsigned/signed */ 451 /* adapter: final Sign conversion -- unsigned/signed */
441 if( dst_format & AUDIO_SIGN ) 452 if( dst_format & AUDIO_SIGN )
453 {
454 fprintf (stderr, "Filter: changeSigned\n");
442 Data->adapter[filter_index++] = changeSigned; 455 Data->adapter[filter_index++] = changeSigned;
456 }
443 457
444 /* final adapter: Size/Endian conversion */ 458 /* final adapter: Size/Endian conversion */
445 switch( dst_format & AUDIO_FORMAT) 459 switch( dst_format & AUDIO_FORMAT)
446 { 460 {
447 case AUDIO_8: 461 case AUDIO_8:
462 fprintf (stderr, "Filter: cut16BitTo8Bit\n");
448 Data->adapter[filter_index++] = cut16BitTo8Bit; 463 Data->adapter[filter_index++] = cut16BitTo8Bit;
449 break; 464 break;
450 case AUDIO_16WRONG: 465 case AUDIO_16WRONG:
466 fprintf (stderr, "Filter: swapBytes\n");
451 Data->adapter[filter_index++] = swapBytes; 467 Data->adapter[filter_index++] = swapBytes;
468 break;
452 } 469 }
453 /* Set up the filter information */ 470 /* Set up the filter information */
454 Data->adapter[filter_index] = NULL; 471 Data->adapter[filter_index] = NULL;
455 Data->needed = (filter_index > 0); 472 Data->needed = (filter_index > 0);
456 return 0; 473 return 0;
457 474
458 error_exit: 475 error_exit:
459 Data->adapter[0] = NULL; 476 Data->adapter[0] = NULL;
460 return -1; 477 return -1;
461 } 478 }
462 /*-------------------------------------------------------------------------*/ 479
463 480 /*
481 * Frank's audio converter has its own ideas about how to represent audio
482 * format, so at least for a transition period we use this to glue his code
483 * to our's.
484 *
485 * + The expand8BitTo16Bit filter will only convert to system byte order.
486 * + The cut16BitTo8Bit filter will only convert from system byte order.
487 * + The changeSigned filter only works on 16-bit samples, system byte order.
488 */
489
490 static char *fmt_to_str(Uint16 fmt)
491 {
492 switch (fmt)
493 {
494 case AUDIO_U8: return " U8"; break;
495 case AUDIO_S8: return " S8"; break;
496 case AUDIO_U16MSB: return "U16MSB"; break;
497 case AUDIO_S16MSB: return "S16MSB"; break;
498 case AUDIO_U16LSB: return "U16LSB"; break;
499 case AUDIO_S16LSB: return "S16LSB"; break;
500 }
501 return "??????";
502 }
503
504 #define IS_8BIT(x) ((x) & 0x0008)
505 #define IS_16BIT(x) ((x) & 0x0010)
506 #define ENDIAN(x) ((x) & 0x1000)
507 #define SIGNED(x) ((x) & 0x8000)
508
509 int Sound_BuildAudioCVT(Sound_AudioCVT *Data,
510 Uint16 src_in_format, Uint8 src_channels, int src_rate,
511 Uint16 dst_in_format, Uint8 dst_channels, int dst_rate)
512 {
513 Uint16 src_format = 0;
514 Uint16 dst_format = 0;
515
516 fprintf (stderr,
517 "format: %s -> %s\n"
518 "channels: %6d -> %6d\n"
519 "rate: %6d -> %6d\n",
520 fmt_to_str (src_in_format), fmt_to_str (dst_in_format),
521 src_channels, dst_channels,
522 src_rate, dst_rate);
523
524 if ( IS_8BIT(src_in_format) && IS_16BIT(dst_in_format) )
525 {
526 src_format |= AUDIO_8;
527
528 /*
529 * Signedness and byte-order changes must wait until the data
530 * has been converted to 16-bit samples.
531 */
532 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) )
533 {
534 dst_format |= AUDIO_SIGN;
535 } /* if */
536
537 if ( ENDIAN(dst_in_format) != ENDIAN(AUDIO_U16SYS) )
538 {
539 dst_format |= AUDIO_16WRONG;
540 } /* if */
541 } /* if */
542 else if ( IS_16BIT(src_in_format) && IS_8BIT(dst_in_format) )
543 {
544 dst_format |= AUDIO_8;
545
546 /*
547 * Byte-order and signedness changes must be made before the data
548 * has been converted to 8-bit samples.
549 */
550 if ( ENDIAN(src_in_format) != ENDIAN(AUDIO_U16SYS) )
551 {
552 src_format |= AUDIO_16WRONG;
553 } /* if */
554
555 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) )
556 {
557 src_format |= AUDIO_SIGN;
558 } /* if */
559 } /* else if */
560 else if ( IS_16BIT(src_in_format) && IS_16BIT(dst_in_format) )
561 {
562 if ( ENDIAN(src_in_format) != ENDIAN(dst_in_format) )
563 {
564 if ( ENDIAN(src_in_format) == ENDIAN(AUDIO_U16SYS) )
565 {
566 dst_format |= AUDIO_16WRONG;
567
568 /*
569 * The data is already is system byte order, so any
570 * signedness change has to be made before changing byte
571 * order.
572 */
573 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) )
574 {
575 src_format |= AUDIO_SIGN;
576 } /* if */
577 } /* if */
578 else
579 {
580 src_format |= AUDIO_16WRONG;
581
582 /*
583 * The data is not in system byte order, so any signedness
584 * change has to be made after changing byte order.
585 */
586 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) )
587 {
588 dst_format |= AUDIO_SIGN;
589 } /* if */
590 } /* else */
591 } /* if */
592 else if ( ENDIAN(src_in_format) != SIGNED(AUDIO_U16SYS) )
593 {
594 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) )
595 {
596 /*
597 * !!! FIXME !!!
598 *
599 * The changeSigned filter only works on system byte
600 * order. In this case, both source and destination is
601 * in opposite byte order, but the sign has to changed
602 * so we need to convert to system byte order, change
603 * sign, and then convert back to the original byte
604 * order again. This is not an optimal solution.
605 */
606 src_format |= ( AUDIO_16WRONG | AUDIO_SIGN );
607 dst_format |= AUDIO_16WRONG;
608 } /* if */
609 } /* else if */
610 else if ( SIGNED(src_in_format) != SIGNED(dst_in_format) )
611 {
612 src_format |= AUDIO_SIGN;
613 } /* else if */
614 } /* else if */
615 else if ( IS_8BIT(src_in_format) && IS_8BIT(dst_in_format) )
616 {
617 /*
618 * !!! FIXME !!!
619 *
620 * The changeSigned filter only works on 16-bit samples, so if
621 * the signedness differs we have to convert from 8 to 16 bits,
622 * change the sign and then convert back to 8 bits again. This
623 * is not an optimal solution.
624 */
625 if ( SIGNED(src_in_format) != SIGNED(dst_in_format) )
626 {
627 src_format |= ( AUDIO_8 | AUDIO_SIGN );
628 dst_format |= AUDIO_8;
629 } /* if */
630
631 /*
632 * !!! FIXME !!!
633 *
634 * The convertMonoToStereo and convertStereoToMono filters only
635 * work with 16-bit samples. So if those are to be applied, we
636 * need to convert to 16-bit samples, and then back again.
637 */
638 if ( src_channels != dst_channels )
639 {
640 src_format |= AUDIO_8;
641 dst_format |= AUDIO_8;
642 } /* if */
643
644 /*
645 * !!! FIXME !!!
646 *
647 * The rate conversion filters almost certainly only work with
648 * 16-bit samples. Yadda, yadda, yadda.
649 */
650 if ( src_rate != dst_rate )
651 {
652 src_format |= AUDIO_8;
653 dst_format |= AUDIO_8;
654 } /* if */
655 } /* else if */
656
657 return BuildAudioCVT(Data, src_format, src_channels, src_rate,
658 dst_format, dst_channels, dst_rate);
659 }
660
661 /*-------------------------------------------------------------------------*/
662