comparison alt_audio_convert.c @ 380:44ed8bdeba74

More fixes from Frank.
author Ryan C. Gordon <icculus@icculus.org>
date Wed, 03 Jul 2002 04:33:23 +0000
parents 24a610dfbbfd
children b1e511c879d1
comparison
equal deleted inserted replaced
379:7e49f4901ceb 380:44ed8bdeba74
157 157
158 158
159 /*-------------------------------------------------------------------------*/ 159 /*-------------------------------------------------------------------------*/
160 static int expand8BitTo16BitSys( AdapterC Data, int length ) 160 static int expand8BitTo16BitSys( AdapterC Data, int length )
161 { 161 {
162 /* !!! Fixme: get rid of <<8 through pointer manipulation --frank */
162 int i; 163 int i;
163 Uint8* inp = Data.buffer; 164 Uint8* inp = Data.buffer;
164 Uint16* buffer = (Uint16*)Data.buffer; 165 Uint16* buffer = (Uint16*)Data.buffer;
165 for( i = length; i--; ) 166 for( i = length - 1; i >= 0; i-- )
166 buffer[i] = inp[i]<<8; 167 buffer[i] = inp[i]<<8;
167 return 2*length; 168 return 2*length;
168 } 169 }
169 170
170 static int expand8BitTo16BitWrong( AdapterC Data, int length ) 171 static int expand8BitTo16BitWrong( AdapterC Data, int length )
171 { 172 {
172 int i; 173 int i;
173 Uint8* inp = Data.buffer; 174 Uint8* inp = Data.buffer;
174 Uint16* buffer = (Uint16*)Data.buffer; 175 Uint16* buffer = (Uint16*)Data.buffer;
175 for( i = length; i--; ) 176 for( i = length - 1; i >= 0; i--)
176 buffer[i] = inp[i]; 177 buffer[i] = inp[i];
177 return 2*length; 178 return 2*length;
178 } 179 }
179 180
180 /*-------------------------------------------------------------------------*/ 181 /*-------------------------------------------------------------------------*/
181 static int expand16BitToFloat( AdapterC Data, int length ) 182 static int expand16BitToFloat( AdapterC Data, int length )
182 { 183 {
183 int i; 184 int i;
184 Sint16* inp = (Sint16*)Data.buffer; 185 Sint16* inp = (Sint16*)Data.buffer;
185 float* buffer = (float*)Data.buffer; 186 float* buffer = (float*)Data.buffer;
186 for( i = length>>1; i--; ) 187 for( i = length>>1 - 1; i >= 0; i-- )
187 buffer[i] = inp[i]*(1./32767); 188 buffer[i] = inp[i]*(1./32767);
188 return 2*length; 189 return 2*length;
189 } 190 }
190 191
191 /*-------------------------------------------------------------------------*/ 192 /*-------------------------------------------------------------------------*/
200 */ 201 */
201 202
202 int i; 203 int i;
203 Uint16 a,b; 204 Uint16 a,b;
204 Uint16* buffer = (Uint16*) Data.buffer; 205 Uint16* buffer = (Uint16*) Data.buffer;
205 for( i = length>>1; i --; ) 206 for( i = length>>1; i >= 0; i-- )
206 { 207 {
207 a = b = buffer[i]; 208 a = b = buffer[i];
208 buffer[i] = ( a << 8 ) | ( b >> 8 ); 209 buffer[i] = ( a << 8 ) | ( b >> 8 );
209 } 210 }
210 return length; 211 return length;
234 { 235 {
235 int i; 236 int i;
236 Uint16* inp = (Uint16*) Data.buffer; 237 Uint16* inp = (Uint16*) Data.buffer;
237 Uint8* buffer = Data.buffer; 238 Uint8* buffer = Data.buffer;
238 length >>= 1; 239 length >>= 1;
240 /* !!! FIXME: Get rid of the >>8 */
239 for( i = 0; i < length; i++ ) 241 for( i = 0; i < length; i++ )
240 buffer[i] = inp[i]>>8; 242 buffer[i] = inp[i]>>8;
241 return length; 243 return length;
242 } 244 }
243 245
246 int i; 248 int i;
247 Uint16* inp = (Uint16*) Data.buffer; 249 Uint16* inp = (Uint16*) Data.buffer;
248 Uint8* buffer = Data.buffer; 250 Uint8* buffer = Data.buffer;
249 length >>= 1; 251 length >>= 1;
250 for( i = 0; i < length; i++ ) 252 for( i = 0; i < length; i++ )
251 buffer[i] = inp[i] & 0xff; 253 buffer[i] = inp[i];
252 return length; 254 return length;
253 } 255 }
254 256
255 /*-------------------------------------------------------------------------*/ 257 /*-------------------------------------------------------------------------*/
256 /* poor mans mmx :-) */ 258 /* poor mans mmx :-) */
257 static int changeSigned( AdapterC Data, int length, Uint32 XOR ) 259 static int changeSigned( AdapterC Data, int length, Uint32 XOR )
258 { 260 {
259 int i; 261 int i;
260 Uint32* buffer = (Uint32*) Data.buffer; 262 Uint32* buffer = (Uint32*) Data.buffer;
261 for( i = length>>2; i--; ) 263 for( i = ( length - 1 ) >> 2; i >= 0; i-- )
262 buffer[i] ^= XOR; 264 buffer[i] ^= XOR;
263 for( i = 4*(length>>2); i < length; i++)
264 ((Uint8*)buffer)[i] ^= ((Uint8*)&XOR)[i&3];
265 return length; 265 return length;
266 } 266 }
267 267
268 static int changeSigned16BitSys( AdapterC Data, int length ) 268 static int changeSigned16BitSys( AdapterC Data, int length )
269 { 269 {
329 static int convertMonoToStereo16Bit( AdapterC Data, int length ) 329 static int convertMonoToStereo16Bit( AdapterC Data, int length )
330 { 330 {
331 int i; 331 int i;
332 Uint16* buffer = (Uint16*) Data.buffer; 332 Uint16* buffer = (Uint16*) Data.buffer;
333 Uint16* dst = (Uint16*)Data.buffer + length - 2; 333 Uint16* dst = (Uint16*)Data.buffer + length - 2;
334 for( i = length>>1; i--; dst-=2 ) 334 for( i = length>>1 - 1; i >= 0; i--, dst-=2 )
335 dst[0] = dst[1] = buffer[i]; 335 dst[0] = dst[1] = buffer[i];
336 return 2*length; 336 return 2*length;
337 } 337 }
338 338
339 static int convertMonoToStereo8Bit( AdapterC Data, int length ) 339 static int convertMonoToStereo8Bit( AdapterC Data, int length )
340 { 340 {
341 int i; 341 int i;
342 Uint8* buffer = Data.buffer; 342 Uint8* buffer = Data.buffer;
343 Uint8* buffer1 = Data.buffer + 1; 343 Uint8* dst = (Uint8*)Data.buffer + length - 2;
344 for( i = length-1; i >= 0; i-- ) 344 for( i = length - 1; i >= 0; i--, dst-=2 )
345 buffer[2*i] = buffer1[2*i] = buffer[i]; 345 dst[0] = dst[1] = buffer[i];
346 return 2*length; 346 return 2*length;
347 } 347 }
348 348
349 /*-------------------------------------------------------------------------*/ 349 /*-------------------------------------------------------------------------*/
350 static int minus5dB( AdapterC Data, int length ) 350 static int minus5dB( AdapterC Data, int length )
351 { 351 {
352 int i; 352 int i;
353 Sint16* buffer = (Sint16*) Data.buffer; 353 Sint16* buffer = (Sint16*) Data.buffer;
354 for(i = length>>1; i--; ) 354 for(i = length>>1 - 1; i >= 0; i-- )
355 buffer[i]= (38084 * (int)buffer[i]) >> 16; 355 buffer[i]= (38084 * (int)buffer[i]) >> 16;
356 return length; 356 return length;
357 } 357 }
358 358
359 /*-------------------------------------------------------------------------*/ 359 /*-------------------------------------------------------------------------*/
362 incrsRate = 0, 362 incrsRate = 0,
363 hlfRate = 1, 363 hlfRate = 1,
364 dblRate = 2 364 dblRate = 2
365 }; 365 };
366 366
367
368 const Fraction Half = {1, 2};
369 const Fraction Double = {2, 1};
370
371 static void initStraigthBuffer( RateConverterBuffer *rcb,
372 int length, Fraction r, int dir )
373 {
374 int i, size, minsize;
375 size = 8 * _fsize;
376 minsize = min( size, length );
377
378 for( i = 0; i < minsize; i++ )
379 {
380 rcb->inbuffer[i] = rcb->buffer[length-size+i];
381 rcb->inbuffer[i+size] = 0;
382 rcb->inbuffer[i+2*size] = rcb->buffer[i];
383 }
384 for( ; i < size; i++ )
385 {
386 rcb->inbuffer[i] = 0;
387 rcb->inbuffer[i+size] = 0;
388 rcb->inbuffer[i+2*size] = 0;
389 }
390
391 length = max( length, size );
392 rcb->flength = rcb->llength = size;
393 rcb->clength = length - size;
394
395 if( dir )
396 {
397 rcb->finp = rcb->inbuffer + 5 * size/2;
398 rcb->cinp = rcb->buffer + length - size/2;
399 rcb->linp = rcb->inbuffer + 3*size/2;
400 rcb->buffer += r.denominator * ( length + size )
401 / r.numerator;
402 }
403 else
404 {
405 rcb->finp = rcb->inbuffer + size/2;
406 rcb->cinp = rcb->buffer + size/2;
407 rcb->linp = rcb->inbuffer + 3*size/2;
408 }
409 }
410
411 static void initLoopBuffer( RateConverterBuffer *rcb,
412 int length, Fraction r, int dir )
413 {
414 /* !!!FIXME: modulo length, take scale into account,
415 check against the Straight part -frank */
416 int i, size;
417 size = 8 * _fsize;
418 for( i = 0; i < size; i++ )
419 {
420 rcb->inbuffer[i] = rcb->buffer[length-size+i];
421 rcb->inbuffer[i+size] = rcb->buffer[i];
422 }
423 rcb->finp = rcb->linp = rcb->inbuffer + size;
424 if( size < 0 )
425 rcb->buffer += r.numerator * ( length + 2 * size )
426 / r.denominator;
427 }
428
367 static void initRateConverterBuffer( RateConverterBuffer *rcb, 429 static void initRateConverterBuffer( RateConverterBuffer *rcb,
368 AdapterC* Data, int length, enum RateConverterType typ ) 430 AdapterC* Data, int length, enum RateConverterType typ )
369 { 431 {
370 int size, minsize, dir; 432 int size, minsize, dir;
371 int den[] = { 0, 1, 2}; 433 Fraction Ratio[] = { {0,0}, {2,1}, {1,2} };
372 int num[] = { 0, 2, 1}; 434
373 int i; 435 Ratio[incrsRate] = Data->filter->ratio;
374
375 den[incrsRate] = Data->filter->denominator;
376 num[incrsRate] = Data->filter->numerator;
377
378 size = 8 * _fsize;
379 dir = ~typ&1; 436 dir = ~typ&1;
380 length >>= 1; 437 length >>= 1;
381 minsize = min( length, size );
382
383 rcb->buffer = (Sint16*)( Data->buffer ); 438 rcb->buffer = (Sint16*)( Data->buffer );
384 439
385 if( Data->mode & SDL_SOUND_Loop ) 440 if( Data->mode & SDL_SOUND_Loop )
386 { 441 initLoopBuffer( rcb, length, Ratio[typ], dir );
387 // !!!FIXME: modulo length, take scale into account,
388 // check against the 'else' part
389 for( i = 0; i < size; i++ )
390 {
391 rcb->inbuffer[i] = rcb->buffer[length-size+i];
392 rcb->inbuffer[i+size] = rcb->buffer[i];
393 }
394 rcb->finp = rcb->linp = rcb->inbuffer + size;
395 if( size < 0 )
396 rcb->buffer += num[typ] * ( length + 2 * size ) / den[typ];
397 }
398 else 442 else
399 { 443 initStraigthBuffer( rcb, length, Ratio[typ], dir );
400 for( i = 0; i < minsize; i++ )
401 {
402 rcb->inbuffer[i] = rcb->buffer[length-size+i];
403 rcb->inbuffer[i+size] = 0;
404 rcb->inbuffer[i+2*size] = rcb->buffer[i];
405 }
406 for( ; i < size; i++ )
407 {
408 rcb->inbuffer[i] = 0;
409 rcb->inbuffer[i+size] = 0;
410 rcb->inbuffer[i+2*size] = 0;
411 }
412 rcb->flength = rcb->llength = size/2 + minsize/2;
413 rcb->clength = length - minsize;
414
415 if( dir )
416 {
417 rcb->finp = rcb->inbuffer + 2 * size + minsize/2;
418 rcb->cinp = rcb->buffer + length - minsize/2;
419 rcb->linp = rcb->inbuffer + size + minsize/2;
420 rcb->buffer += den[typ] * ( length + minsize ) / num[typ];
421 }
422 else
423 {
424 rcb->finp = rcb->inbuffer + size/2;
425 rcb->cinp = rcb->buffer + size/2;
426 rcb->linp = rcb->inbuffer + 3*size/2;
427 }
428 }
429 } 444 }
430 445
431 static void nextRateConverterBuffer( RateConverterBuffer *rcb ) 446 static void nextRateConverterBuffer( RateConverterBuffer *rcb )
432 { 447 {
433 rcb->buffer++; 448 rcb->buffer++;
534 549
535 buffer = (Uint32*) ( Data.buffer + length ); 550 buffer = (Uint32*) ( Data.buffer + length );
536 if( Data.mode != SDL_SOUND_Loop ) 551 if( Data.mode != SDL_SOUND_Loop )
537 mask = Data.filter->mask; 552 mask = Data.filter->mask;
538 length = mask - ( ( length - 1 ) & mask ); 553 length = mask - ( ( length - 1 ) & mask );
539 zero = Data.filter->zero; 554
540 555 for( i = 0; i < length>>2; i++ )
541 for( i = length>>2; i--; )
542 buffer[i] = zero; 556 buffer[i] = zero;
543 for( i = 4*(length>>2); i < length; i++) 557 for( ; i < length; i++ )
544 ((Uint8*)buffer)[i] ^= ((Uint8*)&zero)[i&3]; 558 ((Uint8*)buffer)[i] = ((Uint8*)&zero)[i&3];
545 559
546 return length + ((Uint8*)buffer - Data.buffer); 560 return length + ((Uint8*)buffer - Data.buffer);
547 } 561 }
548 562
549 /*-------------------------------------------------------------------------*/ 563 /*-------------------------------------------------------------------------*/
550 typedef struct{
551 Sint16 numerator;
552 Sint16 denominator;
553 } Fraction;
554
555 const Fraction Half = {1, 2};
556 const Fraction Double = {2, 1};
557
558 /* gives a maximal error of 3% and typical less than 0.2% */ 564 /* gives a maximal error of 3% and typical less than 0.2% */
559 static Fraction findFraction( float Value ) 565 static Fraction findFraction( float Value )
560 { 566 {
561 const Sint8 frac[95]={ 567 const Sint8 frac[95]={
562 2, -1, /* /1 */ 568 2, -1, /* /1 */
621 int i; 627 int i;
622 float w; 628 float w;
623 const float fg = -.018 + .5 * Ratio; 629 const float fg = -.018 + .5 * Ratio;
624 const float omega = 2 * M_PI * fg; 630 const float omega = 2 * M_PI * fg;
625 fprintf( stderr, " phase: %6g \n", phase ); 631 fprintf( stderr, " phase: %6g \n", phase );
626 phase -= 63; 632 phase += 63;
627 for( i = 0; i < 64; i++) 633 for( i = 0; i < 64; i++)
628 { 634 {
629 w = scale * ( KaiserWindow7[i] * ( i + 1 )); 635 w = scale * ( KaiserWindow7[i] * ( i + 1 ));
630 dst[i] = w * sinc( omega * (i+phase) ); 636 dst[i] = w * sinc( omega * (i-phase) );
631 dst[127-i] = w * sinc( omega * (127-i+phase) ); 637 dst[127-i] = w * sinc( omega * (127-i-phase) );
632 } 638 }
639 fprintf( stderr, " center: %6d %6d \n", dst[63], dst[64] );
633 return fg; 640 return fg;
634 } 641 }
635 642
636 static Fraction setupVarFilter( VarFilter* filter, float Ratio ) 643 static Fraction setupVarFilter( VarFilter* filter, float Ratio )
637 { 644 {
642 IRatio = findFraction( Ratio ); 649 IRatio = findFraction( Ratio );
643 // Scale = Ratio < 1. ? 0.0364733 : 0.0211952; 650 // Scale = Ratio < 1. ? 0.0364733 : 0.0211952;
644 Scale = 0.0084778; 651 Scale = 0.0084778;
645 Ratio = min( Ratio, 0.97 ); 652 Ratio = min( Ratio, 0.97 );
646 653
654 filter->ratio = IRatio;
647 n = IRatio.numerator; 655 n = IRatio.numerator;
648 d = IRatio.denominator; 656 d = IRatio.denominator;
649 filter->denominator = d;
650 filter->numerator = n;
651 rd = 1. / d; 657 rd = 1. / d;
652 658
653 fprintf( stderr, "Filter:\n" ); 659 fprintf( stderr, "Filter:\n" );
654 660
655 for( pos = 0; pos < d; pos++ ) 661 for( pos = 0; pos < d; pos++ )
683 Data->add = 0; 689 Data->add = 0;
684 Data->len_add = 0; 690 Data->len_add = 0;
685 } 691 }
686 692
687 /*-------------------------------------------------------------------------*/ 693 /*-------------------------------------------------------------------------*/
694 const Adapter doubleRate[2] = { doubleRateMono, doubleRateStereo };
695 const Adapter halfRate[2] = { halfRateMono, halfRateStereo };
696 const Adapter increaseRate[2] = { increaseRateMono, increaseRateStereo };
697 const Adapter decreaseRate[2] = { decreaseRateMono, decreaseRateStereo };
698
688 static void createRateConverter( Sound_AudioCVT *Data, int* fip, 699 static void createRateConverter( Sound_AudioCVT *Data, int* fip,
689 int SrcRate, int DestRate, int Channel ) 700 int SrcRate, int DestRate, int Channel )
690 { 701 {
691 Fraction f; 702 Fraction f;
692 int filter_index = *fip; 703 int filter_index = *fip;
693 int VarPos = 0; 704 int VarPos = 0;
694 int Mono = 2 - Channel;
695 float Ratio = DestRate; 705 float Ratio = DestRate;
706 int c = Channel - 1;
696 *fip = -1; 707 *fip = -1;
697 708
698 709
699 if( SrcRate < 1 || SrcRate > 1<<18 || 710 if( SrcRate < 1 || SrcRate > 1<<18 ||
700 DestRate < 1 || DestRate > 1<<18 ) return; 711 DestRate < 1 || DestRate > 1<<18 ) return;
705 else 716 else
706 Data->adapter[filter_index++] = minus5dB; 717 Data->adapter[filter_index++] = minus5dB;
707 718
708 while( Ratio > 64./31.) 719 while( Ratio > 64./31.)
709 { 720 {
710 Data->adapter[filter_index++] =
711 Mono ? doubleRateMono : doubleRateStereo;
712 Ratio /= 2.; 721 Ratio /= 2.;
722 Data->adapter[filter_index++] = doubleRate[c];
713 adjustSize( Data, _fsize, Double ); 723 adjustSize( Data, _fsize, Double );
714 } 724 }
715 725
716 while( Ratio < 31./64. ) 726 while( Ratio < 31./64. )
717 { 727 {
718 Data->adapter[filter_index++] =
719 Mono ? halfRateMono : halfRateStereo;
720 Ratio *= 2; 728 Ratio *= 2;
729 Data->adapter[filter_index++] = halfRate[c];
721 adjustSize( Data, _fsize, Half ); 730 adjustSize( Data, _fsize, Half );
722 } 731 }
723 732
724 if( Ratio > 1. ) 733 if( Ratio > 1. )
725 { 734 {
735 Data->adapter[VarPos] = increaseRate[c];
726 f = setupVarFilter( &Data->filter, Ratio ); 736 f = setupVarFilter( &Data->filter, Ratio );
727 Data->adapter[VarPos] =
728 Mono ? increaseRateMono : increaseRateStereo;
729 adjustSize( Data, _fsize, f ); 737 adjustSize( Data, _fsize, f );
730 } 738 }
731 else 739 else
732 { 740 {
741 Data->adapter[filter_index++] = decreaseRate[c];
733 f = setupVarFilter( &Data->filter, Ratio ); 742 f = setupVarFilter( &Data->filter, Ratio );
734 Data->adapter[filter_index++] =
735 Mono ? decreaseRateMono : decreaseRateStereo;
736 adjustSize( Data, _fsize, f ); 743 adjustSize( Data, _fsize, f );
737 } 744 }
738 *fip = filter_index; 745 *fip = filter_index;
739 } 746 }
740 747
869 { 876 {
870 SDL_AudioSpec intrm; 877 SDL_AudioSpec intrm;
871 int filter_index = 0; 878 int filter_index = 0;
872 879
873 if( Data == NULL ) return -1; 880 if( Data == NULL ) return -1;
881 if( dst.size < 8 ) return -1;
882
874 initSize( Data ); 883 initSize( Data );
875 Data->filter.denominator = 0; 884 Data->filter.ratio.denominator = 0;
876 Data->filter.zero = getSilenceValue( dst.format ); 885 Data->filter.zero = getSilenceValue( dst.format );
877 Data->filter.mask = dst.size - 1; 886 Data->filter.mask = dst.size - 1;
887
888
878 889
879 /* Check channels */ 890 /* Check channels */
880 if( src.channels < 1 || src.channels > 2 || 891 if( src.channels < 1 || src.channels > 2 ||
881 dst.channels < 1 || dst.channels > 2 ) goto error_exit; 892 dst.channels < 1 || dst.channels > 2 ) goto error_exit;
882 893
994 1005
995 cont: 1006 cont:
996 } 1007 }
997 fprintf( stderr, " Error: NULL adapter missing\n" ); 1008 fprintf( stderr, " Error: NULL adapter missing\n" );
998 sucess_exit: 1009 sucess_exit:
999 if( Data->filter.denominator ) 1010 if( Data->filter.ratio.denominator )
1000 { 1011 {
1001 fprintf( stderr, "Variable Rate Converter:\n" 1012 fprintf( stderr, "Variable Rate Converter:\n"
1002 " numerator: %3d\n" 1013 " numerator: %3d\n"
1003 " denominator: %3d\n", 1014 " denominator: %3d\n",
1004 Data->filter.denominator, Data->filter.numerator ); 1015 Data->filter.ratio.denominator,
1016 Data->filter.ratio.numerator );
1005 1017
1006 fprintf( stderr, " increment sequence:\n" 1018 fprintf( stderr, " increment sequence:\n"
1007 " " ); 1019 " " );
1008 for( i = 0; i < Data->filter.denominator; i++ ) 1020 for( i = 0; i < Data->filter.ratio.denominator; i++ )
1009 fprintf( stderr, "%1d ", Data->filter.incr[i] ); 1021 fprintf( stderr, "%1d ", Data->filter.incr[i] );
1010 1022
1011 fprintf( stderr, "\n" ); 1023 fprintf( stderr, "\n" );
1012 } 1024 }
1013 else 1025 else
1049 Data->needed = 1; 1061 Data->needed = 1;
1050 1062
1051 show_AudioCVT( Data ); 1063 show_AudioCVT( Data );
1052 fprintf (stderr, "\n" 1064 fprintf (stderr, "\n"
1053 "return value: %d \n\n\n", ret ); 1065 "return value: %d \n\n\n", ret );
1054
1055 return ret; 1066 return ret;
1056 } 1067 }