comparison alt_audio_convert.c @ 420:5b8a07b5162e

Latest altcvt from Frank.
author Ryan C. Gordon <icculus@icculus.org>
date Thu, 26 Sep 2002 04:34:35 +0000
parents b1e511c879d1
children a65440b3a057
comparison
equal deleted inserted replaced
419:25a8f66112fd 420:5b8a07b5162e
123 #include "filter_templates.h" 123 #include "filter_templates.h"
124 #undef Suffix 124 #undef Suffix
125 125
126 126
127 /*-------------------------------------------------------------------------*/ 127 /*-------------------------------------------------------------------------*/
128 static int ConvertAudio( Sound_AudioCVT *Data, 128 int Sound_estimateBufferSize( Sound_AudioCVT *Data, int size )
129 Uint8* buffer, int length, int mode ) 129 {
130 size *= Data->len_mult;
131 size += Data->len_add;
132 return ( size + 3 ) & -4; /* force Size in multipels of 4 Byte */
133 }
134
135 /*-------------------------------------------------------------------------*/
136 int Sound_AltConvertAudio( Sound_AudioCVT *Data,
137 Uint8* buffer, int length, int mode )
130 { 138 {
131 AdapterC Temp; 139 AdapterC Temp;
132 int i; 140 int i;
133 141
134 /* Make sure there's a converter */ 142 /* Make sure there's a converter */
135 if( Data == NULL ) { 143 if( Data == NULL ) {
136 SDL_SetError("altcvt: No converter given"); 144 SDL_SetError("No converter given");
137 return(-1); 145 return(-1);
138 } 146 }
139 147
140 /* Make sure there's data to convert */ 148 /* Make sure there's data to convert */
141 if( buffer == NULL ) { 149 if( buffer == NULL ) {
142 SDL_SetError("altcvt: No buffer allocated for conversion"); 150 SDL_SetError("No buffer allocated for conversion");
143 return(-1); 151 return(-1);
144 } 152 }
145 153
146 if( length < 0 ) { 154 if( length < 0 ) {
147 SDL_SetError("altcvt: Length < 0"); 155 SDL_SetError("Lenght < 0");
148 return(-1); 156 return(-1);
149 } 157 }
150 158
151 /* Set up the conversion and go! */ 159 /* Set up the conversion and go! */
152 Temp.buffer = buffer; 160 Temp.buffer = buffer;
161 169
162 int Sound_ConvertAudio( Sound_AudioCVT *Data ) 170 int Sound_ConvertAudio( Sound_AudioCVT *Data )
163 { 171 {
164 int length; 172 int length;
165 /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */ 173 /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */
166 length = ConvertAudio( Data, Data->buf, Data->len, 0 ); 174 length = Sound_AltConvertAudio( Data, Data->buf, Data->len, 0 );
167 Data->len_cvt = length; 175 Data->len_cvt = length;
168 return length; 176 return length;
169 } 177 }
170 178
171 /*-------------------------------------------------------------------------*/ 179 /*-------------------------------------------------------------------------*/
336 344
337 /*-------------------------------------------------------------------------*/ 345 /*-------------------------------------------------------------------------*/
338 static int convertMonoToStereo16Bit( AdapterC Data, int length ) 346 static int convertMonoToStereo16Bit( AdapterC Data, int length )
339 { 347 {
340 int i; 348 int i;
349 length >>=1;
341 Uint16* buffer = (Uint16*)Data.buffer - 1; 350 Uint16* buffer = (Uint16*)Data.buffer - 1;
342 Uint16* dst = (Uint16*)Data.buffer + length - 2; 351 Uint16* dst = (Uint16*)Data.buffer + 2*length - 2;
343 for( i = length>>1 + 1; --i; dst-=2 ) 352 for( i = length + 1; --i; dst-=2 )
344 dst[0] = dst[1] = buffer[i]; 353 dst[0] = dst[1] = buffer[i];
345 return 2*length; 354 return 4*length;
346 } 355 }
347 356
348 static int convertMonoToStereo8Bit( AdapterC Data, int length ) 357 static int convertMonoToStereo8Bit( AdapterC Data, int length )
349 { 358 {
350 int i; 359 int i;
351 Uint8* buffer = Data.buffer - 1; 360 Uint8* buffer = Data.buffer - 1;
352 Uint8* dst = Data.buffer + length - 2; 361 Uint8* dst = Data.buffer + 2*length - 2;
353 for( i = length + 1; --i; dst-=2 ) 362 for( i = length + 1; --i; dst-=2 )
354 dst[0] = dst[1] = buffer[i]; 363 dst[0] = dst[1] = buffer[i];
355 return 2*length; 364 return 2*length;
356 } 365 }
357 366
366 } 375 }
367 376
368 /*-------------------------------------------------------------------------*/ 377 /*-------------------------------------------------------------------------*/
369 const Fraction Half = {1, 2}; 378 const Fraction Half = {1, 2};
370 const Fraction Double = {2, 1}; 379 const Fraction Double = {2, 1};
380 const Fraction One = {1, 1};
381
371 382
372 static void initStraigthBuffer( RateConverterBuffer *rcb, 383 static void initStraigthBuffer( RateConverterBuffer *rcb,
373 int length, Fraction r, int dir ) 384 int length, Fraction r )
374 { 385 {
375 int i, size, minsize; 386 int i, size, minsize;
376 size = 8 * _fsize; 387 size = 8 * _fsize;
377 minsize = min( size, length ); 388 minsize = min( size, length );
378 389
391 402
392 length = max( length, size ); 403 length = max( length, size );
393 rcb->flength = rcb->llength = size; 404 rcb->flength = rcb->llength = size;
394 rcb->clength = length - size; 405 rcb->clength = length - size;
395 406
396 if( dir ) 407 if( r.numerator < r.denominator )
397 { 408 {
398 rcb->finp = rcb->inbuffer + 5 * size/2; 409 rcb->finp = rcb->inbuffer + 5*size/2;
399 rcb->cinp = rcb->buffer + length - size/2; 410 rcb->cinp = rcb->buffer + length - size/2;
400 rcb->linp = rcb->inbuffer + 3*size/2; 411 rcb->linp = rcb->inbuffer + 3*size/2;
401 rcb->buffer += r.denominator * ( length + size ) 412 rcb->buffer += ( 1 + r.denominator * ( length + size )
402 / r.numerator; 413 / r.numerator ) & -2;
403 } 414 }
404 else 415 else
405 { 416 {
406 rcb->finp = rcb->inbuffer + size/2; 417 rcb->finp = rcb->inbuffer + size/2;
407 rcb->cinp = rcb->buffer + size/2; 418 rcb->cinp = rcb->buffer + size/2;
408 rcb->linp = rcb->inbuffer + 3*size/2; 419 rcb->linp = rcb->inbuffer + 3*size/2;
409 } 420 }
410 } 421 }
411 422
412 static void initLoopBuffer( RateConverterBuffer *rcb, 423 static void initLoopBuffer( RateConverterBuffer *rcb,
413 int length, Fraction r, int dir ) 424 int length, Fraction r )
414 { 425 {
415 /* !!!FIXME: modulo length, take scale into account, 426 /* !!!FIXME: modulo length, take scale into account,
416 check against the Straight part -frank */ 427 check against the Straight part -frank */
417 int i, size; 428 int i, size;
418 size = 8 * _fsize; 429 size = 8 * _fsize;
428 } 439 }
429 440
430 static void initRateConverterBuffer( RateConverterBuffer *rcb, 441 static void initRateConverterBuffer( RateConverterBuffer *rcb,
431 AdapterC* Data, int length, Fraction ratio ) 442 AdapterC* Data, int length, Fraction ratio )
432 { 443 {
433 int dir;
434 dir = ratio.numerator < ratio.denominator ? 1 : 0;
435 length >>= 1; 444 length >>= 1;
436 rcb->buffer = (Sint16*)( Data->buffer ); 445 rcb->buffer = (Sint16*)( Data->buffer );
437 rcb->filter = Data->filter; 446 rcb->filter = Data->filter;
438 447
439 if( Data->mode & SDL_SOUND_Loop ) 448 if( Data->mode & SDL_SOUND_Loop )
440 initLoopBuffer( rcb, length, ratio, dir ); 449 initLoopBuffer( rcb, length, ratio );
441 else 450 else
442 initStraigthBuffer( rcb, length, ratio, dir ); 451 initStraigthBuffer( rcb, length, ratio );
452
453 fprintf( stderr, " finp: %8x length: %8x\n", rcb->finp, rcb->flength );
454 fprintf( stderr, " cinp: %8x length: %8x\n", rcb->cinp, rcb->clength );
455 fprintf( stderr, " linp: %8x length: %8x\n", rcb->linp, rcb->llength );
443 } 456 }
444 457
445 static void nextRateConverterBuffer( RateConverterBuffer *rcb ) 458 static void nextRateConverterBuffer( RateConverterBuffer *rcb )
446 { 459 {
447 rcb->buffer++; 460 rcb->buffer++;
451 } 464 }
452 465
453 typedef Sint16* (*RateConverter)( Sint16*, Sint16*, int, 466 typedef Sint16* (*RateConverter)( Sint16*, Sint16*, int,
454 VarFilter*, RateAux* ); 467 VarFilter*, RateAux* );
455 468
456 static int doRateConversion( RateConverterBuffer* rcb, RateConverter ffp ) 469 static Sint16* doRateConversion( RateConverterBuffer* rcb, RateConverter rc )
457 { 470 {
458 RateAux aux = {0,0}; 471 RateAux aux = {0,0};
459 Sint16 *outp = rcb->buffer; 472 Sint16 *outp = rcb->buffer;
460 VarFilter* filter = rcb->filter; 473 VarFilter* filter = rcb->filter;
461 474
462 outp = (*ffp)( outp, rcb->finp, rcb->flength, filter, &aux ); 475 outp = (*rc)( outp, rcb->finp, rcb->flength, filter, &aux );
463 outp = (*ffp)( outp, rcb->cinp, rcb->clength, filter, &aux ); 476 fprintf( stderr, " outp: %8x aux.carry: %8x\n", outp, aux.carry );
464 outp = (*ffp)( outp, rcb->linp, rcb->llength, filter, &aux ); 477 outp = (*rc)( outp, rcb->cinp, rcb->clength, filter, &aux );
465 return 2 * abs( rcb->buffer - outp ); 478 fprintf( stderr, " outp: %8x aux.carry: %8x\n", outp, aux.carry );
466 } 479 outp = (*rc)( outp, rcb->linp, rcb->llength, filter, &aux );
467 480 fprintf( stderr, " outp: %8x aux.carry: %8x\n", outp, aux.carry );
481 return outp;
482 }
483
484
485 /*-------------------------------------------------------------------------*/
486 static void clearSint16Buffer( Sint8* buffer, Sint16*r )
487 {
488 while( r >= (Sint16*)buffer ) *r-- = 0;
489 }
468 490
469 /*-------------------------------------------------------------------------*/ 491 /*-------------------------------------------------------------------------*/
470 static int doubleRateMono( AdapterC Data, int length ) 492 static int doubleRateMono( AdapterC Data, int length )
471 { 493 {
494 Sint16* r;
495 RateConverterBuffer rcb;
496 initRateConverterBuffer( &rcb, &Data, length, Half );
497 r = 1 + doRateConversion( &rcb, doubleRate1 );
498 clearSint16Buffer( Data.buffer, r );
499 return 2 * ( rcb.buffer - (Sint16*)Data.buffer + 2 );
500 }
501
502 static int doubleRateStereo( AdapterC Data, int length )
503 {
504 Sint16* r;
505 fprintf( stderr, "\n Buffer: %8x length: %8x\n", Data.buffer, length );
506 RateConverterBuffer rcb;
507 initRateConverterBuffer( &rcb, &Data, length, Half );
508 doRateConversion( &rcb, doubleRate2 );
509 nextRateConverterBuffer( &rcb );
510 r = 2 + doRateConversion( &rcb, doubleRate2 );
511 clearSint16Buffer( Data.buffer, r );
512 return 2 * ( rcb.buffer - (Sint16*)Data.buffer + 3 );
513 }
514
515 /*-------------------------------------------------------------------------*/
516 static int halfRateMono( AdapterC Data, int length )
517 {
518 Sint16* r;
472 RateConverterBuffer rcb; 519 RateConverterBuffer rcb;
473 initRateConverterBuffer( &rcb, &Data, length, Double ); 520 initRateConverterBuffer( &rcb, &Data, length, Double );
474 return doRateConversion( &rcb, doubleRate1 ); 521 r = doRateConversion( &rcb, halfRate1 );
475 } 522 return 2 * ( r - (Sint16*)Data.buffer );
476 523 }
477 static int doubleRateStereo( AdapterC Data, int length ) 524
478 { 525 static int halfRateStereo( AdapterC Data, int length )
526 {
527 Sint16* r;
479 RateConverterBuffer rcb; 528 RateConverterBuffer rcb;
480 initRateConverterBuffer( &rcb, &Data, length, Double ); 529 initRateConverterBuffer( &rcb, &Data, length, Double );
481 doRateConversion( &rcb, doubleRate2 );
482 nextRateConverterBuffer( &rcb );
483 return 2 + doRateConversion( &rcb, doubleRate2 );
484 }
485
486 /*-------------------------------------------------------------------------*/
487 static int halfRateMono( AdapterC Data, int length )
488 {
489 RateConverterBuffer rcb;
490 initRateConverterBuffer( &rcb, &Data, length, Half );
491 return doRateConversion( &rcb, halfRate1 );
492 }
493
494 static int halfRateStereo( AdapterC Data, int length )
495 {
496 RateConverterBuffer rcb;
497 initRateConverterBuffer( &rcb, &Data, length, Half );
498 doRateConversion( &rcb, halfRate2 ); 530 doRateConversion( &rcb, halfRate2 );
499 nextRateConverterBuffer( &rcb ); 531 nextRateConverterBuffer( &rcb );
500 return 2 + doRateConversion( &rcb, halfRate2 ); 532 r = doRateConversion( &rcb, halfRate2 );
533 return 2 * ( r - (Sint16*)Data.buffer );
501 } 534 }
502 535
503 /*-------------------------------------------------------------------------*/ 536 /*-------------------------------------------------------------------------*/
504 static int increaseRateMono( AdapterC Data, int length ) 537 static int increaseRateMono( AdapterC Data, int length )
505 { 538 {
539 Sint16* r;
506 RateConverterBuffer rcb; 540 RateConverterBuffer rcb;
507 initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio ); 541 initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio );
508 return doRateConversion( &rcb, increaseRate1 ); 542 r = doRateConversion( &rcb, increaseRate1 );
543 clearSint16Buffer( Data.buffer, r );
544 return 2 * ( rcb.buffer - (Sint16*)Data.buffer + 1 );
509 } 545 }
510 546
511 static int increaseRateStereo( AdapterC Data, int length ) 547 static int increaseRateStereo( AdapterC Data, int length )
512 { 548 {
549 Sint16* r;
550 fprintf( stderr, "\n Buffer: %8x length: %8x\n", Data.buffer, length );
513 RateConverterBuffer rcb; 551 RateConverterBuffer rcb;
514 initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio ); 552 initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio );
515 doRateConversion( &rcb, increaseRate2 ); 553 doRateConversion( &rcb, increaseRate2 );
516 nextRateConverterBuffer( &rcb ); 554 nextRateConverterBuffer( &rcb );
517 return 2 + doRateConversion( &rcb, increaseRate2 ); 555 r = doRateConversion( &rcb, increaseRate2 );
556 clearSint16Buffer( Data.buffer, r );
557 return 2 * ( rcb.buffer - (Sint16*)Data.buffer + 1 );
518 } 558 }
519 559
520 /*-------------------------------------------------------------------------*/ 560 /*-------------------------------------------------------------------------*/
521 static int decreaseRateMono( AdapterC Data, int length ) 561 static int decreaseRateMono( AdapterC Data, int length )
522 { 562 {
563 Sint16* r;
523 RateConverterBuffer rcb; 564 RateConverterBuffer rcb;
524 initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio ); 565 initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio );
525 return doRateConversion( &rcb, decreaseRate1 ); 566 r = doRateConversion( &rcb, decreaseRate1 );
567 return 2 * ( r - (Sint16*)Data.buffer );
526 } 568 }
527 569
528 static int decreaseRateStereo( AdapterC Data, int length ) 570 static int decreaseRateStereo( AdapterC Data, int length )
529 { 571 {
572 Sint16* r;
530 RateConverterBuffer rcb; 573 RateConverterBuffer rcb;
531 initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio ); 574 initRateConverterBuffer( &rcb, &Data, length, Data.filter->ratio );
532 doRateConversion( &rcb, decreaseRate2 ); 575 doRateConversion( &rcb, decreaseRate2 );
533 nextRateConverterBuffer( &rcb ); 576 nextRateConverterBuffer( &rcb );
534 return 2 + doRateConversion( &rcb, decreaseRate2 ); 577 r = doRateConversion( &rcb, decreaseRate2 );
535 } 578 return 2 * ( r - (Sint16*)Data.buffer );
536
537 /*-------------------------------------------------------------------------*/
538 static int padSilence( AdapterC Data, int length )
539 {
540 Uint32 zero, *buffer;
541 int i, mask = 0;
542
543 buffer = (Uint32*) ( Data.buffer + length );
544 if( Data.mode != SDL_SOUND_Loop )
545 mask = Data.filter->mask;
546 length = mask - ( ( length - 1 ) & mask );
547
548 for( i = 0; i < length>>2; i++ )
549 buffer[i] = zero;
550 for( ; i < length; i++ )
551 ((Uint8*)buffer)[i] = ((Uint8*)&zero)[i&3];
552
553 return length + ((Uint8*)buffer - Data.buffer);
554 } 579 }
555 580
556 /*-------------------------------------------------------------------------*/ 581 /*-------------------------------------------------------------------------*/
557 /* gives a maximal error of 3% and typical less than 0.2% */ 582 /* gives a maximal error of 3% and typical less than 0.2% */
558 static Fraction findFraction( float Value ) 583 static Fraction findFraction( float Value )
631 } 656 }
632 fprintf( stderr, " center: %6d %6d \n", dst[63], dst[64] ); 657 fprintf( stderr, " center: %6d %6d \n", dst[63], dst[64] );
633 return fg; 658 return fg;
634 } 659 }
635 660
636 static Fraction setupVarFilter( VarFilter* filter, float Ratio ) 661 static Fraction setupVarFilter( Sound_AudioCVT *Data, float Ratio )
637 { 662 {
638 int pos,n,d, incr, phase = 0; 663 int pos,n,d, incr, phase = 0;
639 float Scale, rd, fg; 664 float Scale, rd, fg;
640 Fraction IRatio; 665 Fraction IRatio;
666 VarFilter* filter = &Data->filter;
641 667
642 IRatio = findFraction( Ratio ); 668 IRatio = findFraction( Ratio );
643 // Scale = Ratio < 1. ? 0.0364733 : 0.0211952; 669 // Scale = Ratio < 1. ? 0.0364733 : 0.0211952;
644 Scale = 0.0084778; 670 Scale = 0.0084778;
645 Ratio = min( Ratio, 0.97 ); 671 Ratio = min( Ratio, 0.97 );
663 IRatio.numerator = d; 689 IRatio.numerator = d;
664 IRatio.denominator = n; 690 IRatio.denominator = n;
665 return IRatio; 691 return IRatio;
666 } 692 }
667 /*-------------------------------------------------------------------------*/ 693 /*-------------------------------------------------------------------------*/
694 static void initAudioCVT( Sound_AudioCVT *Data )
695 {
696 Data->len_ratio = 1.;
697 Data->len_mult = 1;
698 Data->add = 0;
699 Data->len_add = 0;
700 Data->filter_index = 0;
701 }
702
668 static void adjustSize( Sound_AudioCVT *Data, int add, Fraction f ) 703 static void adjustSize( Sound_AudioCVT *Data, int add, Fraction f )
669 { 704 {
670
671 double ratio = f.numerator / (double) f.denominator; 705 double ratio = f.numerator / (double) f.denominator;
672 Data->len_ratio *= ratio; 706 Data->len_ratio *= ratio;
673 Data->len_mult = max( Data->len_mult, ceil(Data->len_ratio) ); 707 Data->len_mult = max( Data->len_mult, ceil(Data->len_ratio) );
674 Data->add = ratio * (Data->add + add); 708 Data->add = ratio * (Data->add + add);
675 Data->len_add = max( Data->len_add, ceil(Data->add) ); 709 Data->len_add = max( Data->len_add, ceil(Data->add) );
676 } 710 }
677 711
678 static void initSize( Sound_AudioCVT *Data ) 712 static Adapter* addAdapter( Sound_AudioCVT *Data, Adapter a )
679 { 713 {
680 Data->len_ratio = 1.; 714 Data->adapter[Data->filter_index] = a;
681 Data->len_mult = 1; 715 return &Data->adapter[Data->filter_index++];
682 Data->add = 0; 716 }
683 Data->len_add = 0; 717
684 } 718 static void addHAdapter( Sound_AudioCVT *Data, Adapter a )
719 {
720 adjustSize( Data, 0, Half );
721 addAdapter( Data, a );
722 }
723
724 static void addDAdapter( Sound_AudioCVT *Data, Adapter a )
725 {
726 adjustSize( Data, 0, Double );
727 addAdapter( Data, a );
728 }
729
685 730
686 /*-------------------------------------------------------------------------*/ 731 /*-------------------------------------------------------------------------*/
687 const Adapter doubleRate[2] = { doubleRateMono, doubleRateStereo }; 732 const Adapter doubleRate[2] = { doubleRateMono, doubleRateStereo };
688 const Adapter halfRate[2] = { halfRateMono, halfRateStereo }; 733 const Adapter halfRate[2] = { halfRateMono, halfRateStereo };
689 const Adapter increaseRate[2] = { increaseRateMono, increaseRateStereo }; 734 const Adapter increaseRate[2] = { increaseRateMono, increaseRateStereo };
690 const Adapter decreaseRate[2] = { decreaseRateMono, decreaseRateStereo }; 735 const Adapter decreaseRate[2] = { decreaseRateMono, decreaseRateStereo };
691 736
692 static void createRateConverter( Sound_AudioCVT *Data, int* fip, 737 static int createRateConverter( Sound_AudioCVT *Data,
693 int SrcRate, int DestRate, int channel ) 738 int SrcRate, int DestRate, int channel )
694 { 739 {
695 const int c = channel - 1; 740 const int c = channel - 1;
696 const int size = 16 * channel * _fsize; 741 const int size = 16 * channel * _fsize;
697 int filter_index = *fip; 742 Adapter* AdapterPos;
698 int VarPos = 0;
699 float Ratio = DestRate; 743 float Ratio = DestRate;
700 Fraction f; 744 Fraction f;
701 *fip = -1;
702
703 745
704 if( SrcRate < 1 || SrcRate > 1<<18 || 746 if( SrcRate < 1 || SrcRate > 1<<18 ||
705 DestRate < 1 || DestRate > 1<<18 ) return; 747 DestRate < 1 || DestRate > 1<<18 ) return -1;
706 Ratio /= SrcRate; 748 Ratio /= SrcRate;
707 749
708 if( Ratio > 1.) 750 AdapterPos = addAdapter( Data, minus5dB );
709 VarPos = filter_index++; 751
752 while( Ratio > 64./31.)
753 {
754 Ratio /= 2.;
755 addAdapter( Data, doubleRate[c] );
756 adjustSize( Data, size, Double );
757 }
758
759 while( Ratio < 31./64. )
760 {
761 Ratio *= 2;
762 addAdapter( Data, halfRate[c] );
763 adjustSize( Data, size, Half );
764 }
765
766 if( Ratio > 1. )
767 {
768 *AdapterPos = increaseRate[c];
769 f = setupVarFilter( Data, Ratio );
770 adjustSize( Data, size, f );
771 }
710 else 772 else
711 Data->adapter[filter_index++] = minus5dB; 773 {
712 774 f = setupVarFilter( Data, Ratio );
713 while( Ratio > 64./31.) 775 addAdapter( Data, decreaseRate[c]);
714 {
715 Ratio /= 2.;
716 Data->adapter[filter_index++] = doubleRate[c];
717 adjustSize( Data, size, Double );
718 }
719
720 while( Ratio < 31./64. )
721 {
722 Ratio *= 2;
723 Data->adapter[filter_index++] = halfRate[c];
724 adjustSize( Data, size, Half );
725 }
726
727 if( Ratio > 1. )
728 {
729 Data->adapter[VarPos] = increaseRate[c];
730 f = setupVarFilter( &Data->filter, Ratio );
731 adjustSize( Data, size, f ); 776 adjustSize( Data, size, f );
732 } 777 }
778
779 return 0;
780 }
781
782 /*-------------------------------------------------------------------------*/
783 static void createFormatConverter16Bit(Sound_AudioCVT *Data,
784 SDL_AudioSpec src, SDL_AudioSpec dst )
785 {
786 if( src.channels == 2 && dst.channels == 1 )
787 {
788 if( !IS_SYSENDIAN(src) )
789 addAdapter( Data, swapBytes );
790
791 if( IS_SIGNED(src) )
792 addHAdapter( Data, convertStereoToMonoS16Bit );
793 else
794 addHAdapter( Data, convertStereoToMonoU16Bit );
795
796 if( !IS_SYSENDIAN(dst) )
797 addAdapter( Data, swapBytes );
798 }
799 else if( IS_SYSENDIAN(src) != IS_SYSENDIAN(dst) )
800 addAdapter( Data, swapBytes );
801
802 if( IS_SIGNED(src) != IS_SIGNED(dst) )
803 {
804 if( IS_SYSENDIAN(dst) )
805 addAdapter( Data, changeSigned16BitSys );
806 else
807 addAdapter( Data, changeSigned16BitWrong );
808 }
809
810 if( src.channels == 1 && dst.channels == 2 )
811 addDAdapter( Data, convertMonoToStereo16Bit );
812 }
813
814 /*-------------------------------------------------------------------------*/
815 static void createFormatConverter8Bit(Sound_AudioCVT *Data,
816 SDL_AudioSpec src, SDL_AudioSpec dst )
817 {
818 if( IS_16BIT(src) )
819 {
820 if( IS_SYSENDIAN(src) )
821 addHAdapter( Data, cut16BitSysTo8Bit );
822 else
823 addHAdapter( Data, cut16BitWrongTo8Bit );
824 }
825
826 if( src.channels == 2 && dst.channels == 1 )
827 {
828 if( IS_SIGNED(src) )
829 addHAdapter( Data, convertStereoToMonoS8Bit );
830 else
831 addHAdapter( Data, convertStereoToMonoU8Bit );
832 }
833
834 if( IS_SIGNED(src) != IS_SIGNED(dst) )
835 addDAdapter( Data, changeSigned8Bit );
836
837 if( src.channels == 1 && dst.channels == 2 )
838 addDAdapter( Data, convertMonoToStereo8Bit );
839
840 if( !IS_8BIT(dst) )
841 {
842 if( IS_SYSENDIAN(dst) )
843 addDAdapter( Data, expand8BitTo16BitSys );
844 else
845 addDAdapter( Data, expand8BitTo16BitWrong );
846 }
847 }
848
849 /*-------------------------------------------------------------------------*/
850 static void createFormatConverter(Sound_AudioCVT *Data,
851 SDL_AudioSpec src, SDL_AudioSpec dst )
852 {
853 if( IS_FLOAT(src) )
854 addHAdapter( Data, cutFloatTo16Bit );
855
856 if( IS_8BIT(src) || IS_8BIT(dst) )
857 createFormatConverter8Bit( Data, src, dst);
733 else 858 else
734 { 859 createFormatConverter16Bit( Data, src, dst);
735 Data->adapter[filter_index++] = decreaseRate[c];
736 f = setupVarFilter( &Data->filter, Ratio );
737 adjustSize( Data, size, f );
738 }
739 *fip = filter_index;
740 }
741
742 /*-------------------------------------------------------------------------*/
743 static void createFormatConverter16Bit(Sound_AudioCVT *Data, int* fip,
744 SDL_AudioSpec src, SDL_AudioSpec dst )
745 {
746 int filter_index = *fip;
747
748 if( src.channels == 2 && dst.channels == 1 )
749 {
750 adjustSize( Data, 0, Half );
751
752 if( !IS_SYSENDIAN(src) )
753 Data->adapter[filter_index++] = swapBytes;
754
755 if( IS_SIGNED(src) )
756 Data->adapter[filter_index++] = convertStereoToMonoS16Bit;
757 else
758 Data->adapter[filter_index++] = convertStereoToMonoU16Bit;
759
760 if( !IS_SYSENDIAN(dst) )
761 Data->adapter[filter_index++] = swapBytes;
762 }
763 else if( IS_SYSENDIAN(src) != IS_SYSENDIAN(dst) )
764 Data->adapter[filter_index++] = swapBytes;
765
766 if( IS_SIGNED(src) != IS_SIGNED(dst) )
767 {
768 if( IS_SYSENDIAN(dst) )
769 Data->adapter[filter_index++] = changeSigned16BitSys;
770 else
771 Data->adapter[filter_index++] = changeSigned16BitWrong;
772 }
773
774 if( src.channels == 1 && dst.channels == 2 )
775 {
776 adjustSize( Data, 0, Double );
777 Data->adapter[filter_index++] = convertMonoToStereo16Bit;
778 }
779
780 *fip = filter_index;
781 }
782
783 /*-------------------------------------------------------------------------*/
784 static void createFormatConverter8Bit(Sound_AudioCVT *Data, int *fip,
785 SDL_AudioSpec src, SDL_AudioSpec dst )
786 {
787 int filter_index = *fip;
788 if( IS_16BIT(src) )
789 {
790 adjustSize( Data, 0, Half );
791
792 if( IS_SYSENDIAN(src) )
793 Data->adapter[filter_index++] = cut16BitSysTo8Bit;
794 else
795 Data->adapter[filter_index++] = cut16BitWrongTo8Bit;
796 }
797
798 if( src.channels == 2 && dst.channels == 1 )
799 {
800 adjustSize( Data, 0, Half );
801
802 if( IS_SIGNED(src) )
803 Data->adapter[filter_index++] = convertStereoToMonoS8Bit;
804 else
805 Data->adapter[filter_index++] = convertStereoToMonoU8Bit;
806 }
807
808 if( IS_SIGNED(src) != IS_SIGNED(dst) )
809 Data->adapter[filter_index++] = changeSigned8Bit;
810
811 if( src.channels == 1 && dst.channels == 2 )
812 {
813 adjustSize( Data, 0, Double );
814 Data->adapter[filter_index++] = convertMonoToStereo8Bit;
815 }
816
817 if( !IS_8BIT(dst) )
818 {
819 adjustSize( Data, 0, Double );
820 if( IS_SYSENDIAN(dst) )
821 Data->adapter[filter_index++] = expand8BitTo16BitSys;
822 else
823 Data->adapter[filter_index++] = expand8BitTo16BitWrong;
824 }
825
826 *fip = filter_index;
827 }
828
829 /*-------------------------------------------------------------------------*/
830 static void createFormatConverter(Sound_AudioCVT *Data, int *fip,
831 SDL_AudioSpec src, SDL_AudioSpec dst )
832 {
833 int filter_index = *fip;
834
835 if( IS_FLOAT(src) )
836 {
837 Data->adapter[filter_index++] = cutFloatTo16Bit;
838 adjustSize( Data, 0, Half );
839 }
840
841 if( IS_8BIT(src) || IS_8BIT(dst) )
842 createFormatConverter8Bit( Data, &filter_index, src, dst);
843 else
844 createFormatConverter16Bit( Data, &filter_index, src, dst);
845 860
846 if( IS_FLOAT(dst) ) 861 if( IS_FLOAT(dst) )
847 { 862 addDAdapter( Data, expand16BitToFloat );
848 Data->adapter[filter_index++] = expand16BitToFloat; 863 }
849 adjustSize( Data, 0, Double ); 864
850 } 865 /*-------------------------------------------------------------------------*/
851 866 int Sound_AltBuildAudioCVT( Sound_AudioCVT *Data,
852 *fip = filter_index;
853 }
854
855 /*-------------------------------------------------------------------------*/
856 Uint32 getSilenceValue( Uint16 format )
857 {
858 const static float fzero[] = {0.0000001};
859 switch( format )
860 {
861 case 0x0020: return *(Uint32*) fzero;
862 default: ;
863 }
864 return 0;
865 }
866
867 /*-------------------------------------------------------------------------*/
868 int BuildAudioCVT( Sound_AudioCVT *Data,
869 SDL_AudioSpec src, SDL_AudioSpec dst ) 867 SDL_AudioSpec src, SDL_AudioSpec dst )
870 { 868 {
871 SDL_AudioSpec intrm; 869 SDL_AudioSpec im;
872 int filter_index = 0;
873 870
874 if( Data == NULL ) return -1; 871 if( Data == NULL ) return -1;
875 if( dst.size < 8 ) return -1; 872
876 873 initAudioCVT( Data );
877 initSize( Data );
878 Data->filter.ratio.denominator = 0; 874 Data->filter.ratio.denominator = 0;
879 Data->filter.zero = getSilenceValue( dst.format );
880 Data->filter.mask = dst.size - 1; 875 Data->filter.mask = dst.size - 1;
881
882
883 876
884 /* Check channels */ 877 /* Check channels */
885 if( src.channels < 1 || src.channels > 2 || 878 if( src.channels < 1 || src.channels > 2 ||
886 dst.channels < 1 || dst.channels > 2 ) goto error_exit; 879 dst.channels < 1 || dst.channels > 2 ) goto error_exit;
887 880
888 /* If no frequency conversion is needed, go straight to dst format */ 881 if( src.freq != dst.freq )
889 if( src.freq == dst.freq ) 882 {
890 { 883 /* Convert to intermidiate format: signed 16Bit System-Endian */
891 createFormatConverter( Data, &filter_index, src, dst ); 884 im.format = AUDIO_S16SYS;
892 goto sucess_exit; 885 im.channels = min( src.channels, dst.channels );
893 } 886 createFormatConverter( Data, src, im );
894
895 /* Convert to signed 16Bit System-Endian */
896 intrm.format = AUDIO_S16SYS;
897 intrm.channels = min( src.channels, dst.channels );
898 createFormatConverter( Data, &filter_index, src, intrm );
899 887
900 /* Do rate conversion */ 888 /* Do rate conversion */
901 if( src.channels == 2 && dst.channels == 2 ) 889 if( createRateConverter( Data, src.freq, dst.freq, im.channels ) )
902 createRateConverter( Data, &filter_index, src.freq, dst.freq, 2 ); 890 goto error_exit;
903 else 891
904 createRateConverter( Data, &filter_index, src.freq, dst.freq, 1 ); 892 src = im;
905 /* propagate error */ 893 }
906 if( filter_index < 0 ) goto error_exit;
907 894
908 /* Convert to final format */ 895 /* Convert to final format */
909 createFormatConverter( Data, &filter_index, intrm, dst ); 896 createFormatConverter( Data, src, dst );
910 897
911 /* Set up the filter information */ 898 /* Finalize adapter list */
912 sucess_exit: 899 addAdapter( Data, NULL );
913 Data->adapter[filter_index++] = padSilence;
914 Data->adapter[filter_index] = NULL;
915 /* !!! FIXME: Is it okay to assign NULL to a function pointer? 900 /* !!! FIXME: Is it okay to assign NULL to a function pointer?
916 Borland says no. -frank */ 901 Borland says no. -frank */
917 return 0; 902 return 0;
918 903
919 error_exit: 904 error_exit:
968 AdapterDesc(halfRateStereo), 953 AdapterDesc(halfRateStereo),
969 AdapterDesc(increaseRateMono), 954 AdapterDesc(increaseRateMono),
970 AdapterDesc(increaseRateStereo), 955 AdapterDesc(increaseRateStereo),
971 AdapterDesc(decreaseRateMono), 956 AdapterDesc(decreaseRateMono),
972 AdapterDesc(decreaseRateStereo), 957 AdapterDesc(decreaseRateStereo),
973 AdapterDesc(padSilence),
974 { NULL, "----------NULL-----------\n" } 958 { NULL, "----------NULL-----------\n" }
975 }; 959 };
976 960
977 fprintf( stderr, "Sound_AudioCVT:\n" ); 961 fprintf( stderr, "Sound_AudioCVT:\n" );
978 fprintf( stderr, " needed: %8d\n", Data->needed ); 962 fprintf( stderr, " needed: %8d\n", Data->needed );
1023 } 1007 }
1024 1008
1025 1009
1026 int Sound_BuildAudioCVT(Sound_AudioCVT *Data, 1010 int Sound_BuildAudioCVT(Sound_AudioCVT *Data,
1027 Uint16 src_format, Uint8 src_channels, int src_rate, 1011 Uint16 src_format, Uint8 src_channels, int src_rate,
1028 Uint16 dst_format, Uint8 dst_channels, int dst_rate, Uint32 dst_size ) 1012 Uint16 dst_format, Uint8 dst_channels, int dst_rate )
1029 { 1013 {
1030 SDL_AudioSpec src, dst; 1014 SDL_AudioSpec src, dst;
1031 int ret; 1015 int ret;
1032 1016
1033 fprintf (stderr, 1017 fprintf (stderr,
1037 "channels: %6d -> %6d\n" 1021 "channels: %6d -> %6d\n"
1038 "rate: %6d -> %6d\n" 1022 "rate: %6d -> %6d\n"
1039 "size: don't care -> %#7x\n\n", 1023 "size: don't care -> %#7x\n\n",
1040 fmt_to_str (src_format), fmt_to_str (dst_format), 1024 fmt_to_str (src_format), fmt_to_str (dst_format),
1041 src_channels, dst_channels, 1025 src_channels, dst_channels,
1042 src_rate, dst_rate, 1026 src_rate, dst_rate );
1043 dst_size );
1044 1027
1045 src.format = src_format; 1028 src.format = src_format;
1046 src.channels = src_channels; 1029 src.channels = src_channels;
1047 src.freq = src_rate; 1030 src.freq = src_rate;
1048 1031
1049 dst.format = dst_format; 1032 dst.format = dst_format;
1050 dst.channels = dst_channels; 1033 dst.channels = dst_channels;
1051 dst.freq = dst_rate; 1034 dst.freq = dst_rate;
1052 dst.size = dst_size; 1035
1053 1036 ret = Sound_AltBuildAudioCVT( Data, src, dst );
1054 ret = BuildAudioCVT( Data, src, dst );
1055 Data->needed = 1; 1037 Data->needed = 1;
1056 1038
1057 show_AudioCVT( Data ); 1039 show_AudioCVT( Data );
1058 fprintf (stderr, "\n" 1040 fprintf (stderr, "\n"
1059 "return value: %d \n\n\n", ret ); 1041 "return value: %d \n\n\n", ret );