Mercurial > SDL_sound_CoreAudio
comparison alt_audio_convert.c @ 373:24a610dfbbfd
More altcvt updates from Frank.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sat, 29 Jun 2002 04:08:17 +0000 |
parents | 1b463ef9bcc2 |
children | 44ed8bdeba74 |
comparison
equal
deleted
inserted
replaced
372:ee0678efd4a3 | 373:24a610dfbbfd |
---|---|
32 | 32 |
33 #ifndef min | 33 #ifndef min |
34 #define min(x, y) ( ((x) < (y)) ? (x) : (y) ) | 34 #define min(x, y) ( ((x) < (y)) ? (x) : (y) ) |
35 #endif | 35 #endif |
36 | 36 |
37 #ifndef max | |
38 #define max(x, y) ( ((x) > (y)) ? (x) : (y) ) | |
39 #endif | |
40 | |
37 #ifndef abs | 41 #ifndef abs |
38 #define abs(x) ( ((x) > (0)) ? (x) : -(x) ) | 42 #define abs(x) ( ((x) > (0)) ? (x) : -(x) ) |
39 #endif | 43 #endif |
40 | 44 |
41 | 45 |
144 | 148 |
145 int Sound_ConvertAudio( Sound_AudioCVT *Data ) | 149 int Sound_ConvertAudio( Sound_AudioCVT *Data ) |
146 { | 150 { |
147 int length; | 151 int length; |
148 /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */ | 152 /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */ |
149 length = ConvertAudio( Data, Data->buf, Data->len, 0 ); | 153 length = ConvertAudio( Data, Data->buf, Data->len, 12 ); |
150 Data->len_cvt = length; | 154 Data->len_cvt = length; |
151 return length; | 155 return length; |
152 } | 156 } |
153 | 157 |
154 | 158 |
247 buffer[i] = inp[i] & 0xff; | 251 buffer[i] = inp[i] & 0xff; |
248 return length; | 252 return length; |
249 } | 253 } |
250 | 254 |
251 /*-------------------------------------------------------------------------*/ | 255 /*-------------------------------------------------------------------------*/ |
252 static int changeSigned( AdapterC Data, int length, int XOR ) | 256 /* poor mans mmx :-) */ |
257 static int changeSigned( AdapterC Data, int length, Uint32 XOR ) | |
253 { | 258 { |
254 int i; | 259 int i; |
255 Uint32* buffer = (Uint32*) Data.buffer; | 260 Uint32* buffer = (Uint32*) Data.buffer; |
256 for( i = length>>2; i--; ) | 261 for( i = length>>2; i--; ) |
257 buffer[i] ^= XOR; | 262 buffer[i] ^= XOR; |
323 /*-------------------------------------------------------------------------*/ | 328 /*-------------------------------------------------------------------------*/ |
324 static int convertMonoToStereo16Bit( AdapterC Data, int length ) | 329 static int convertMonoToStereo16Bit( AdapterC Data, int length ) |
325 { | 330 { |
326 int i; | 331 int i; |
327 Uint16* buffer = (Uint16*) Data.buffer; | 332 Uint16* buffer = (Uint16*) Data.buffer; |
328 Uint16* dst = (Uint16*)Data.buffer + length; | 333 Uint16* dst = (Uint16*)Data.buffer + length - 2; |
329 for( i = length>>1; i--; dst-=2 ) | 334 for( i = length>>1; i--; dst-=2 ) |
330 dst[-1] = dst[-2] = buffer[i]; | 335 dst[0] = dst[1] = buffer[i]; |
331 return 2*length; | 336 return 2*length; |
332 } | 337 } |
333 | 338 |
334 static int convertMonoToStereo8Bit( AdapterC Data, int length ) | 339 static int convertMonoToStereo8Bit( AdapterC Data, int length ) |
335 { | 340 { |
336 int i; | 341 int i; |
337 Uint8* buffer = Data.buffer; | 342 Uint8* buffer = Data.buffer; |
338 Uint8* dst = Data.buffer + 2*length; | 343 Uint8* buffer1 = Data.buffer + 1; |
339 for( i = length; i--; dst-=2 ) | 344 for( i = length-1; i >= 0; i-- ) |
340 dst[-1] = dst[-2] = buffer[i]; | 345 buffer[2*i] = buffer1[2*i] = buffer[i]; |
341 return 2*length; | 346 return 2*length; |
342 } | 347 } |
343 | 348 |
344 /*-------------------------------------------------------------------------*/ | 349 /*-------------------------------------------------------------------------*/ |
345 static int minus5dB( AdapterC Data, int length ) | 350 static int minus5dB( AdapterC Data, int length ) |
346 { | 351 { |
347 int i; | 352 int i; |
348 Sint16* buffer = (Sint16*) Data.buffer; | 353 Sint16* buffer = (Sint16*) Data.buffer; |
349 for(i = length>>1; i--; ) | 354 for(i = length>>1; i--; ) |
350 buffer[i]= 38084 * buffer[i] >> 16; | 355 buffer[i]= (38084 * (int)buffer[i]) >> 16; |
351 return length; | 356 return length; |
352 } | 357 } |
353 | 358 |
354 /*-------------------------------------------------------------------------*/ | 359 /*-------------------------------------------------------------------------*/ |
355 enum RateConverterType{ | 360 enum RateConverterType{ |
356 dcrsRate = 0, | 361 dcrsRate = -1, |
357 incrsRate = 1, | 362 incrsRate = 0, |
358 hlfRate = 2, | 363 hlfRate = 1, |
359 dblRate = 3 | 364 dblRate = 2 |
360 }; | 365 }; |
361 | 366 |
362 static void initRateConverterBuffer( RateConverterBuffer *rcb, | 367 static void initRateConverterBuffer( RateConverterBuffer *rcb, |
363 AdapterC* Data, int length, enum RateConverterType typ ) | 368 AdapterC* Data, int length, enum RateConverterType typ ) |
364 { | 369 { |
365 int size, minsize, dir; | 370 int size, minsize, dir; |
366 int den[] = { 0, 0, 1, 2}; | 371 int den[] = { 0, 1, 2}; |
367 int num[] = { 0, 0, 2, 1}; | 372 int num[] = { 0, 2, 1}; |
368 int i; | 373 int i; |
369 | 374 |
370 den[incrsRate] = Data->filter->denominator; | 375 den[incrsRate] = Data->filter->denominator; |
371 num[incrsRate] = Data->filter->numerator; | 376 num[incrsRate] = Data->filter->numerator; |
372 | 377 |
373 size = 8 * _fsize; | 378 size = 8 * _fsize; |
374 dir = typ&1; | 379 dir = ~typ&1; |
375 length >>= 1; | 380 length >>= 1; |
376 minsize = min( length, size ); | 381 minsize = min( length, size ); |
377 | 382 |
378 rcb->buffer = (Sint16*)( Data->buffer ); | 383 rcb->buffer = (Sint16*)( Data->buffer ); |
379 | 384 |
380 if( Data->mode & SDL_AI_Loop ) | 385 if( Data->mode & SDL_SOUND_Loop ) |
381 { | 386 { |
382 // !!!FIXME: modulo length, take scale into account, | 387 // !!!FIXME: modulo length, take scale into account, |
383 // check against the 'else' part | 388 // check against the 'else' part |
384 for( i = 0; i < size; i++ ) | 389 for( i = 0; i < size; i++ ) |
385 { | 390 { |
396 { | 401 { |
397 rcb->inbuffer[i] = rcb->buffer[length-size+i]; | 402 rcb->inbuffer[i] = rcb->buffer[length-size+i]; |
398 rcb->inbuffer[i+size] = 0; | 403 rcb->inbuffer[i+size] = 0; |
399 rcb->inbuffer[i+2*size] = rcb->buffer[i]; | 404 rcb->inbuffer[i+2*size] = rcb->buffer[i]; |
400 } | 405 } |
401 for( i = 0; i < size; i++ ) | 406 for( ; i < size; i++ ) |
402 { | 407 { |
403 rcb->inbuffer[i] = 0; | 408 rcb->inbuffer[i] = 0; |
404 rcb->inbuffer[i+size] = 0; | 409 rcb->inbuffer[i+size] = 0; |
405 rcb->inbuffer[i+2*size] = 0; | 410 rcb->inbuffer[i+2*size] = 0; |
406 } | 411 } |
519 doRateConversion( &rcb, decreaseRate2, Data.filter ); | 524 doRateConversion( &rcb, decreaseRate2, Data.filter ); |
520 nextRateConverterBuffer( &rcb ); | 525 nextRateConverterBuffer( &rcb ); |
521 return doRateConversion( &rcb, decreaseRate2, Data.filter ); | 526 return doRateConversion( &rcb, decreaseRate2, Data.filter ); |
522 } | 527 } |
523 | 528 |
529 /*-------------------------------------------------------------------------*/ | |
530 static int padSilence( AdapterC Data, int length ) | |
531 { | |
532 Uint32 zero, *buffer; | |
533 int i, mask = 0; | |
534 | |
535 buffer = (Uint32*) ( Data.buffer + length ); | |
536 if( Data.mode != SDL_SOUND_Loop ) | |
537 mask = Data.filter->mask; | |
538 length = mask - ( ( length - 1 ) & mask ); | |
539 zero = Data.filter->zero; | |
540 | |
541 for( i = length>>2; i--; ) | |
542 buffer[i] = zero; | |
543 for( i = 4*(length>>2); i < length; i++) | |
544 ((Uint8*)buffer)[i] ^= ((Uint8*)&zero)[i&3]; | |
545 | |
546 return length + ((Uint8*)buffer - Data.buffer); | |
547 } | |
524 | 548 |
525 /*-------------------------------------------------------------------------*/ | 549 /*-------------------------------------------------------------------------*/ |
526 typedef struct{ | 550 typedef struct{ |
551 Sint16 numerator; | |
527 Sint16 denominator; | 552 Sint16 denominator; |
528 Sint16 numerator; | |
529 } Fraction; | 553 } Fraction; |
554 | |
555 const Fraction Half = {1, 2}; | |
556 const Fraction Double = {2, 1}; | |
530 | 557 |
531 /* gives a maximal error of 3% and typical less than 0.2% */ | 558 /* gives a maximal error of 3% and typical less than 0.2% */ |
532 static Fraction findFraction( float Value ) | 559 static Fraction findFraction( float Value ) |
533 { | 560 { |
534 const Sint8 frac[95]={ | 561 const Sint8 frac[95]={ |
577 { | 604 { |
578 if( x > -1e-24 && x < 1e-24 ) return 1.; | 605 if( x > -1e-24 && x < 1e-24 ) return 1.; |
579 else return sin(x)/x; | 606 else return sin(x)/x; |
580 } | 607 } |
581 | 608 |
582 static void calculateVarFilter( Sint16* dst, | 609 static float calculateVarFilter( Sint16* dst, |
583 float Ratio, float phase, float scale ) | 610 float Ratio, float phase, float scale ) |
584 { | 611 { |
585 const Uint16 KaiserWindow7[]= { | 612 const Uint16 KaiserWindow7[]= { |
586 22930, 16292, 14648, 14288, 14470, 14945, 15608, 16404, | 613 22930, 16292, 14648, 14288, 14470, 14945, 15608, 16404, |
587 17304, 18289, 19347, 20467, 21644, 22872, 24145, 25460, | 614 17304, 18289, 19347, 20467, 21644, 22872, 24145, 25460, |
588 26812, 28198, 29612, 31052, 32513, 33991, 35482, 36983, | 615 26812, 28198, 29612, 31052, 32513, 33991, 35482, 36983, |
593 64815, 64422, 63946, 63389, 62753, 62039, 61251, 60391 }; | 620 64815, 64422, 63946, 63389, 62753, 62039, 61251, 60391 }; |
594 int i; | 621 int i; |
595 float w; | 622 float w; |
596 const float fg = -.018 + .5 * Ratio; | 623 const float fg = -.018 + .5 * Ratio; |
597 const float omega = 2 * M_PI * fg; | 624 const float omega = 2 * M_PI * fg; |
625 fprintf( stderr, " phase: %6g \n", phase ); | |
598 phase -= 63; | 626 phase -= 63; |
599 for( i = 0; i < 64; i++) | 627 for( i = 0; i < 64; i++) |
600 { | 628 { |
601 w = scale * ( KaiserWindow7[i] * ( i + 1 )); | 629 w = scale * ( KaiserWindow7[i] * ( i + 1 )); |
602 dst[i] = w * sinc( omega * (i+phase) ); | 630 dst[i] = w * sinc( omega * (i+phase) ); |
603 dst[127-i] = w * sinc( omega * (127-i+phase) ); | 631 dst[127-i] = w * sinc( omega * (127-i+phase) ); |
604 } | 632 } |
605 } | 633 return fg; |
606 | 634 } |
607 static void setupVarFilter( VarFilter* filter, float Ratio ) | 635 |
608 { | 636 static Fraction setupVarFilter( VarFilter* filter, float Ratio ) |
609 int i,n,d, incr, phase = 0; | 637 { |
610 float Scale, rd; | 638 int pos,n,d, incr, phase = 0; |
639 float Scale, rd, fg; | |
611 Fraction IRatio; | 640 Fraction IRatio; |
612 | 641 |
613 IRatio = findFraction( Ratio ); | 642 IRatio = findFraction( Ratio ); |
614 Scale = Ratio < 1. ? 0.0364733 : 0.0211952; | 643 // Scale = Ratio < 1. ? 0.0364733 : 0.0211952; |
615 Ratio = min( Ratio, 1/Ratio ); | 644 Scale = 0.0084778; |
645 Ratio = min( Ratio, 0.97 ); | |
616 | 646 |
617 n = IRatio.numerator; | 647 n = IRatio.numerator; |
618 d = IRatio.denominator; | 648 d = IRatio.denominator; |
619 filter->denominator = d; | 649 filter->denominator = d; |
620 filter->numerator = n; | 650 filter->numerator = n; |
621 rd = 1. / d; | 651 rd = 1. / d; |
622 | 652 |
623 for( i = 0; i < d; i++ ) | 653 fprintf( stderr, "Filter:\n" ); |
624 { | 654 |
625 calculateVarFilter( filter->c[i], Ratio, phase*rd, Scale ); | 655 for( pos = 0; pos < d; pos++ ) |
656 { | |
657 fg = calculateVarFilter( filter->c[pos], Ratio, phase*rd, Scale ); | |
626 phase += n; | 658 phase += n; |
627 filter->incr[i] = phase / d; | 659 filter->incr[pos] = phase / d; |
628 phase %= d; | 660 phase %= d; |
629 } | 661 } |
662 fprintf( stderr, " fg: %6g\n\n", fg ); | |
663 /* !!!FIXME: get rid of the inversion -Frank*/ | |
664 IRatio.numerator = d; | |
665 IRatio.denominator = n; | |
666 return IRatio; | |
667 } | |
668 /*-------------------------------------------------------------------------*/ | |
669 static void adjustSize( Sound_AudioCVT *Data, int add, Fraction f ) | |
670 { | |
671 | |
672 double ratio = f.numerator / (double) f.denominator; | |
673 Data->len_ratio *= ratio; | |
674 Data->len_mult = max( Data->len_mult, ceil(Data->len_ratio) ); | |
675 Data->add = ratio * (Data->add + add); | |
676 Data->len_add = max( Data->len_add, ceil(Data->add) ); | |
677 } | |
678 | |
679 static void initSize( Sound_AudioCVT *Data ) | |
680 { | |
681 Data->len_ratio = 1.; | |
682 Data->len_mult = 1; | |
683 Data->add = 0; | |
684 Data->len_add = 0; | |
630 } | 685 } |
631 | 686 |
632 /*-------------------------------------------------------------------------*/ | 687 /*-------------------------------------------------------------------------*/ |
633 static void createRateConverter( Sound_AudioCVT *Data, int* fip, | 688 static void createRateConverter( Sound_AudioCVT *Data, int* fip, |
634 int SrcRate, int DestRate, int Channel ) | 689 int SrcRate, int DestRate, int Channel ) |
635 { | 690 { |
691 Fraction f; | |
636 int filter_index = *fip; | 692 int filter_index = *fip; |
637 | |
638 int VarPos = 0; | 693 int VarPos = 0; |
639 int Mono = 2 - Channel; | 694 int Mono = 2 - Channel; |
640 float Ratio = DestRate; | 695 float Ratio = DestRate; |
641 *fip = -1; | 696 *fip = -1; |
642 | 697 |
653 while( Ratio > 64./31.) | 708 while( Ratio > 64./31.) |
654 { | 709 { |
655 Data->adapter[filter_index++] = | 710 Data->adapter[filter_index++] = |
656 Mono ? doubleRateMono : doubleRateStereo; | 711 Mono ? doubleRateMono : doubleRateStereo; |
657 Ratio /= 2.; | 712 Ratio /= 2.; |
658 Data->mult *= 2; | 713 adjustSize( Data, _fsize, Double ); |
659 Data->add *= 2; | |
660 Data->add += _fsize; | |
661 } | 714 } |
662 | 715 |
663 while( Ratio < 31./64. ) | 716 while( Ratio < 31./64. ) |
664 { | 717 { |
665 Data->adapter[filter_index++] = | 718 Data->adapter[filter_index++] = |
666 Mono ? halfRateMono : halfRateStereo; | 719 Mono ? halfRateMono : halfRateStereo; |
667 Ratio *= 2; | 720 Ratio *= 2; |
721 adjustSize( Data, _fsize, Half ); | |
668 } | 722 } |
669 | 723 |
670 if( Ratio > 1. ) | 724 if( Ratio > 1. ) |
671 { | 725 { |
672 setupVarFilter( &Data->filter, Ratio ); | 726 f = setupVarFilter( &Data->filter, Ratio ); |
673 Data->adapter[VarPos] = | 727 Data->adapter[VarPos] = |
674 Mono ? increaseRateMono : increaseRateStereo; | 728 Mono ? increaseRateMono : increaseRateStereo; |
675 Data->mult *= 2; | 729 adjustSize( Data, _fsize, f ); |
676 Data->add *= 2; | |
677 Data->add += _fsize; | |
678 } | 730 } |
679 else | 731 else |
680 { | 732 { |
681 setupVarFilter( &Data->filter, Ratio ); | 733 f = setupVarFilter( &Data->filter, Ratio ); |
682 Data->adapter[filter_index++] = | 734 Data->adapter[filter_index++] = |
683 Mono ? decreaseRateMono : decreaseRateStereo; | 735 Mono ? decreaseRateMono : decreaseRateStereo; |
736 adjustSize( Data, _fsize, f ); | |
684 } | 737 } |
685 *fip = filter_index; | 738 *fip = filter_index; |
686 } | 739 } |
687 | 740 |
688 /*-------------------------------------------------------------------------*/ | 741 /*-------------------------------------------------------------------------*/ |
691 { | 744 { |
692 int filter_index = *fip; | 745 int filter_index = *fip; |
693 | 746 |
694 if( src.channels == 2 && dst.channels == 1 ) | 747 if( src.channels == 2 && dst.channels == 1 ) |
695 { | 748 { |
696 Data->add /= 2; | 749 adjustSize( Data, 0, Half ); |
697 Data->mult /= 2; | |
698 | 750 |
699 if( !IS_SYSENDIAN(src) ) | 751 if( !IS_SYSENDIAN(src) ) |
700 Data->adapter[filter_index++] = swapBytes; | 752 Data->adapter[filter_index++] = swapBytes; |
701 | 753 |
702 if( IS_SIGNED(src) ) | 754 if( IS_SIGNED(src) ) |
718 Data->adapter[filter_index++] = changeSigned16BitWrong; | 770 Data->adapter[filter_index++] = changeSigned16BitWrong; |
719 } | 771 } |
720 | 772 |
721 if( src.channels == 1 && dst.channels == 2 ) | 773 if( src.channels == 1 && dst.channels == 2 ) |
722 { | 774 { |
723 Data->add *= 2; | 775 adjustSize( Data, 0, Double ); |
724 Data->mult *= 2; | |
725 Data->adapter[filter_index++] = convertMonoToStereo16Bit; | 776 Data->adapter[filter_index++] = convertMonoToStereo16Bit; |
726 } | 777 } |
727 | 778 |
728 *fip = filter_index; | 779 *fip = filter_index; |
729 } | 780 } |
733 SDL_AudioSpec src, SDL_AudioSpec dst ) | 784 SDL_AudioSpec src, SDL_AudioSpec dst ) |
734 { | 785 { |
735 int filter_index = *fip; | 786 int filter_index = *fip; |
736 if( IS_16BIT(src) ) | 787 if( IS_16BIT(src) ) |
737 { | 788 { |
738 Data->add /= 2; | 789 adjustSize( Data, 0, Half ); |
739 Data->mult /= 2; | |
740 | 790 |
741 if( IS_SYSENDIAN(src) ) | 791 if( IS_SYSENDIAN(src) ) |
742 Data->adapter[filter_index++] = cut16BitSysTo8Bit; | 792 Data->adapter[filter_index++] = cut16BitSysTo8Bit; |
743 else | 793 else |
744 Data->adapter[filter_index++] = cut16BitWrongTo8Bit; | 794 Data->adapter[filter_index++] = cut16BitWrongTo8Bit; |
745 } | 795 } |
746 | 796 |
747 if( src.channels == 2 && dst.channels == 1 ) | 797 if( src.channels == 2 && dst.channels == 1 ) |
748 { | 798 { |
749 Data->add /= 2; | 799 adjustSize( Data, 0, Half ); |
750 Data->mult /= 2; | |
751 | 800 |
752 if( IS_SIGNED(src) ) | 801 if( IS_SIGNED(src) ) |
753 Data->adapter[filter_index++] = convertStereoToMonoS8Bit; | 802 Data->adapter[filter_index++] = convertStereoToMonoS8Bit; |
754 else | 803 else |
755 Data->adapter[filter_index++] = convertStereoToMonoU8Bit; | 804 Data->adapter[filter_index++] = convertStereoToMonoU8Bit; |
758 if( IS_SIGNED(src) != IS_SIGNED(dst) ) | 807 if( IS_SIGNED(src) != IS_SIGNED(dst) ) |
759 Data->adapter[filter_index++] = changeSigned8Bit; | 808 Data->adapter[filter_index++] = changeSigned8Bit; |
760 | 809 |
761 if( src.channels == 1 && dst.channels == 2 ) | 810 if( src.channels == 1 && dst.channels == 2 ) |
762 { | 811 { |
763 Data->add *= 2; | 812 adjustSize( Data, 0, Double ); |
764 Data->mult *= 2; | |
765 Data->adapter[filter_index++] = convertMonoToStereo8Bit; | 813 Data->adapter[filter_index++] = convertMonoToStereo8Bit; |
766 } | 814 } |
767 | 815 |
768 if( !IS_8BIT(dst) ) | 816 if( !IS_8BIT(dst) ) |
769 { | 817 { |
770 Data->add *= 2; | 818 adjustSize( Data, 0, Double ); |
771 Data->mult *= 2; | |
772 if( IS_SYSENDIAN(dst) ) | 819 if( IS_SYSENDIAN(dst) ) |
773 Data->adapter[filter_index++] = expand8BitTo16BitSys; | 820 Data->adapter[filter_index++] = expand8BitTo16BitSys; |
774 else | 821 else |
775 Data->adapter[filter_index++] = expand8BitTo16BitWrong; | 822 Data->adapter[filter_index++] = expand8BitTo16BitWrong; |
776 } | 823 } |
785 int filter_index = *fip; | 832 int filter_index = *fip; |
786 | 833 |
787 if( IS_FLOAT(src) ) | 834 if( IS_FLOAT(src) ) |
788 { | 835 { |
789 Data->adapter[filter_index++] = cutFloatTo16Bit; | 836 Data->adapter[filter_index++] = cutFloatTo16Bit; |
790 Data->mult /= 2; | 837 adjustSize( Data, 0, Half ); |
791 Data->add /= 2; | |
792 } | 838 } |
793 | 839 |
794 if( IS_8BIT(src) || IS_8BIT(dst) ) | 840 if( IS_8BIT(src) || IS_8BIT(dst) ) |
795 createFormatConverter8Bit( Data, &filter_index, src, dst); | 841 createFormatConverter8Bit( Data, &filter_index, src, dst); |
796 else | 842 else |
797 createFormatConverter16Bit( Data, &filter_index, src, dst); | 843 createFormatConverter16Bit( Data, &filter_index, src, dst); |
798 | 844 |
799 if( IS_FLOAT(dst) ) | 845 if( IS_FLOAT(dst) ) |
800 { | 846 { |
801 Data->adapter[filter_index++] = expand16BitToFloat; | 847 Data->adapter[filter_index++] = expand16BitToFloat; |
802 Data->mult *= 2; | 848 adjustSize( Data, 0, Double ); |
803 Data->add *= 2; | |
804 } | 849 } |
805 | 850 |
806 *fip = filter_index; | 851 *fip = filter_index; |
807 } | 852 } |
808 | 853 |
854 /*-------------------------------------------------------------------------*/ | |
855 Uint32 getSilenceValue( Uint16 format ) | |
856 { | |
857 const static float fzero[] = {0.0000001}; | |
858 switch( format ) | |
859 { | |
860 case 0x0020: return *(Uint32*) fzero; | |
861 default: ; | |
862 } | |
863 return 0; | |
864 } | |
809 | 865 |
810 /*-------------------------------------------------------------------------*/ | 866 /*-------------------------------------------------------------------------*/ |
811 int BuildAudioCVT( Sound_AudioCVT *Data, | 867 int BuildAudioCVT( Sound_AudioCVT *Data, |
812 SDL_AudioSpec src, SDL_AudioSpec dst ) | 868 SDL_AudioSpec src, SDL_AudioSpec dst ) |
813 { | 869 { |
814 SDL_AudioSpec intrm; | 870 SDL_AudioSpec intrm; |
815 int filter_index = 0; | 871 int filter_index = 0; |
816 | 872 |
817 if( Data == NULL ) return -1; | 873 if( Data == NULL ) return -1; |
818 Data->mult = 1.; | 874 initSize( Data ); |
819 Data->add = 0; | |
820 Data->filter.denominator = 0; | 875 Data->filter.denominator = 0; |
876 Data->filter.zero = getSilenceValue( dst.format ); | |
877 Data->filter.mask = dst.size - 1; | |
821 | 878 |
822 /* Check channels */ | 879 /* Check channels */ |
823 if( src.channels < 1 || src.channels > 2 || | 880 if( src.channels < 1 || src.channels > 2 || |
824 dst.channels < 1 || dst.channels > 2 ) goto error_exit; | 881 dst.channels < 1 || dst.channels > 2 ) goto error_exit; |
825 | 882 |
846 /* Convert to final format */ | 903 /* Convert to final format */ |
847 createFormatConverter( Data, &filter_index, intrm, dst ); | 904 createFormatConverter( Data, &filter_index, intrm, dst ); |
848 | 905 |
849 /* Set up the filter information */ | 906 /* Set up the filter information */ |
850 sucess_exit: | 907 sucess_exit: |
908 Data->adapter[filter_index++] = padSilence; | |
909 Data->adapter[filter_index] = NULL; | |
851 /* !!! FIXME: Is it okay to assign NULL to a function pointer? | 910 /* !!! FIXME: Is it okay to assign NULL to a function pointer? |
852 Borland says no. -frank */ | 911 Borland says no. -frank */ |
853 Data->adapter[filter_index] = NULL; | |
854 Data->needed = filter_index > 0 ? 1 : 0; | |
855 return 0; | 912 return 0; |
856 | 913 |
857 error_exit: | 914 error_exit: |
858 /* !!! FIXME: Is it okay to assign NULL to a function pointer? | 915 /* !!! FIXME: Is it okay to assign NULL to a function pointer? |
859 Borland says no. -frank */ | 916 Borland says no. -frank */ |
860 Data->adapter[0] = NULL; | 917 Data->adapter[0] = NULL; |
861 Data->needed = 0; | |
862 return -1; | 918 return -1; |
863 } | 919 } |
864 | 920 |
865 /*-------------------------------------------------------------------------*/ | 921 /*-------------------------------------------------------------------------*/ |
866 static char *fmt_to_str(Uint16 fmt) | 922 static char *fmt_to_str(Uint16 fmt) |
907 AdapterDesc(halfRateStereo), | 963 AdapterDesc(halfRateStereo), |
908 AdapterDesc(increaseRateMono), | 964 AdapterDesc(increaseRateMono), |
909 AdapterDesc(increaseRateStereo), | 965 AdapterDesc(increaseRateStereo), |
910 AdapterDesc(decreaseRateMono), | 966 AdapterDesc(decreaseRateMono), |
911 AdapterDesc(decreaseRateStereo), | 967 AdapterDesc(decreaseRateStereo), |
912 { NULL, "----------NULL-----------" } | 968 AdapterDesc(padSilence), |
969 { NULL, "----------NULL-----------\n" } | |
913 }; | 970 }; |
914 | 971 |
915 fprintf( stderr, "\nAdapter List: \n" ); | 972 fprintf( stderr, "Sound_AudioCVT:\n" ); |
973 fprintf( stderr, " needed: %8d\n", Data->needed ); | |
974 fprintf( stderr, " add: %8g\n", Data->add ); | |
975 fprintf( stderr, " len_add: %8d\n", Data->len_add ); | |
976 fprintf( stderr, " len_ratio: %8g\n", Data->len_ratio ); | |
977 fprintf( stderr, " len_mult: %8d\n", Data->len_mult ); | |
978 fprintf( stderr, " filter->mask: %#7x\n", Data->filter.mask ); | |
979 fprintf( stderr, "\n" ); | |
980 | |
981 fprintf( stderr, "Adapter List: \n" ); | |
916 for( i = 0; i < 32; i++ ) | 982 for( i = 0; i < 32; i++ ) |
917 { | 983 { |
918 for( j = 0; j < SDL_TABLESIZE(AdapterDescription); j++ ) | 984 for( j = 0; j < SDL_TABLESIZE(AdapterDescription); j++ ) |
919 { | 985 { |
920 if( Data->adapter[i] == AdapterDescription[j].adapter ) | 986 if( Data->adapter[i] == AdapterDescription[j].adapter ) |
921 { | 987 { |
922 fprintf( stderr, " %s\n", AdapterDescription[j].name ); | 988 fprintf( stderr, " %s \n", AdapterDescription[j].name ); |
923 if( Data->adapter[i] == NULL ) goto sucess_exit; | 989 if( Data->adapter[i] == NULL ) goto sucess_exit; |
924 goto cont; | 990 goto cont; |
925 } | 991 } |
926 } | 992 } |
927 fprintf( stderr, " Error: unknown adapter\n" ); | 993 fprintf( stderr, " Error: unknown adapter\n" ); |
931 fprintf( stderr, " Error: NULL adapter missing\n" ); | 997 fprintf( stderr, " Error: NULL adapter missing\n" ); |
932 sucess_exit: | 998 sucess_exit: |
933 if( Data->filter.denominator ) | 999 if( Data->filter.denominator ) |
934 { | 1000 { |
935 fprintf( stderr, "Variable Rate Converter:\n" | 1001 fprintf( stderr, "Variable Rate Converter:\n" |
936 "numerator: %3d, denominator: %3d\n", | 1002 " numerator: %3d\n" |
1003 " denominator: %3d\n", | |
937 Data->filter.denominator, Data->filter.numerator ); | 1004 Data->filter.denominator, Data->filter.numerator ); |
938 | 1005 |
939 fprintf( stderr, "increment sequence: " ); | 1006 fprintf( stderr, " increment sequence:\n" |
1007 " " ); | |
940 for( i = 0; i < Data->filter.denominator; i++ ) | 1008 for( i = 0; i < Data->filter.denominator; i++ ) |
941 fprintf( stderr, "%3d ", Data->filter.incr[i] ); | 1009 fprintf( stderr, "%1d ", Data->filter.incr[i] ); |
942 | 1010 |
943 fprintf( stderr, "\n" ); | 1011 fprintf( stderr, "\n" ); |
944 } | 1012 } |
945 else | 1013 else |
946 { | 1014 { |
949 } | 1017 } |
950 | 1018 |
951 | 1019 |
952 int Sound_BuildAudioCVT(Sound_AudioCVT *Data, | 1020 int Sound_BuildAudioCVT(Sound_AudioCVT *Data, |
953 Uint16 src_format, Uint8 src_channels, int src_rate, | 1021 Uint16 src_format, Uint8 src_channels, int src_rate, |
954 Uint16 dst_format, Uint8 dst_channels, int dst_rate) | 1022 Uint16 dst_format, Uint8 dst_channels, int dst_rate, Uint32 dst_size ) |
955 { | 1023 { |
956 SDL_AudioSpec src, dst; | 1024 SDL_AudioSpec src, dst; |
957 int ret; | 1025 int ret; |
958 | 1026 |
959 fprintf (stderr, | 1027 fprintf (stderr, |
960 "Sound_BuildAudioCVT() :\n" | 1028 "Sound_BuildAudioCVT():\n" |
961 "-----------------------\n" | 1029 "-----------------------------\n" |
962 "format: %s -> %s\n" | 1030 "format: %s -> %s\n" |
963 "channels: %6d -> %6d\n" | 1031 "channels: %6d -> %6d\n" |
964 "rate: %6d -> %6d\n", | 1032 "rate: %6d -> %6d\n" |
1033 "size: don't care -> %#7x\n\n", | |
965 fmt_to_str (src_format), fmt_to_str (dst_format), | 1034 fmt_to_str (src_format), fmt_to_str (dst_format), |
966 src_channels, dst_channels, | 1035 src_channels, dst_channels, |
967 src_rate, dst_rate); | 1036 src_rate, dst_rate, |
1037 dst_size ); | |
968 | 1038 |
969 src.format = src_format; | 1039 src.format = src_format; |
970 src.channels = src_channels; | 1040 src.channels = src_channels; |
971 src.freq = src_rate; | 1041 src.freq = src_rate; |
972 | 1042 |
973 dst.format = dst_format; | 1043 dst.format = dst_format; |
974 dst.channels = dst_channels; | 1044 dst.channels = dst_channels; |
975 dst.freq = dst_rate; | 1045 dst.freq = dst_rate; |
1046 dst.size = dst_size; | |
976 | 1047 |
977 ret = BuildAudioCVT( Data, src, dst ); | 1048 ret = BuildAudioCVT( Data, src, dst ); |
978 Data->len_mult = Data->mult > 1 ? ceil(Data->mult) : 1; | 1049 Data->needed = 1; |
979 Data->len_ratio = Data->mult; | |
980 | 1050 |
981 show_AudioCVT( Data ); | 1051 show_AudioCVT( Data ); |
982 fprintf (stderr, "\n" | 1052 fprintf (stderr, "\n" |
983 "return value: %d \n", ret ); | 1053 "return value: %d \n\n\n", ret ); |
984 | 1054 |
985 return ret; | 1055 return ret; |
986 } | 1056 } |