Mercurial > SDL_sound_CoreAudio
comparison alt_audio_convert.c @ 371:1b463ef9bcc2
More work from Frank.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Tue, 25 Jun 2002 17:15:03 +0000 |
parents | 84d6c604eaa9 |
children | 24a610dfbbfd |
comparison
equal
deleted
inserted
replaced
370:12023d47b716 | 371:1b463ef9bcc2 |
---|---|
137 Temp.filter = &Data->filter; | 137 Temp.filter = &Data->filter; |
138 | 138 |
139 for( i = 0; Data->adapter[i] != NULL; i++ ) | 139 for( i = 0; Data->adapter[i] != NULL; i++ ) |
140 length = (*Data->adapter[i])( Temp, length); | 140 length = (*Data->adapter[i])( Temp, length); |
141 | 141 |
142 return length; | |
143 } | |
144 | |
145 int Sound_ConvertAudio( Sound_AudioCVT *Data ) | |
146 { | |
147 int length; | |
148 /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */ | |
149 length = ConvertAudio( Data, Data->buf, Data->len, 0 ); | |
142 Data->len_cvt = length; | 150 Data->len_cvt = length; |
143 return length; | 151 return length; |
144 } | |
145 | |
146 int Sound_ConvertAudio( Sound_AudioCVT *Data ) | |
147 { | |
148 /* !!! FIXME: Try the looping stuff under certain circumstances? --ryan. */ | |
149 return ConvertAudio( Data, Data->buf, Data->len, 0 ); | |
150 } | 152 } |
151 | 153 |
152 | 154 |
153 /*-------------------------------------------------------------------------*/ | 155 /*-------------------------------------------------------------------------*/ |
154 static int expand8BitTo16BitSys( AdapterC Data, int length ) | 156 static int expand8BitTo16BitSys( AdapterC Data, int length ) |
278 { | 280 { |
279 int i; | 281 int i; |
280 Sint16* buffer = (Sint16*) Data.buffer; | 282 Sint16* buffer = (Sint16*) Data.buffer; |
281 Sint16* src = (Sint16*) Data.buffer; | 283 Sint16* src = (Sint16*) Data.buffer; |
282 length >>= 2; | 284 length >>= 2; |
283 for( i = 0; i < length; i++ ) | 285 for( i = 0; i < length; i++, src+=2 ) |
284 buffer[i] = ((int) *(src++) + *(src++) ) >> 1; | 286 buffer[i] = ((int) src[0] + src[1] ) >> 1; |
285 return 2*length; | 287 return 2*length; |
286 } | 288 } |
287 | 289 |
288 static int convertStereoToMonoU16Bit( AdapterC Data, int length ) | 290 static int convertStereoToMonoU16Bit( AdapterC Data, int length ) |
289 { | 291 { |
290 int i; | 292 int i; |
291 Uint16* buffer = (Uint16*) Data.buffer; | 293 Uint16* buffer = (Uint16*) Data.buffer; |
292 Uint16* src = (Uint16*) Data.buffer; | 294 Uint16* src = (Uint16*) Data.buffer; |
293 length >>= 2; | 295 length >>= 2; |
294 for( i = 0; i < length; i++ ) | 296 for( i = 0; i < length; i++, src+=2 ) |
295 buffer[i] = ((int) *(src++) + *(src++) ) >> 1; | 297 buffer[i] = ((int) src[0] + src[1] ) >> 1; |
296 return 2*length; | 298 return 2*length; |
297 } | 299 } |
298 | 300 |
299 static int convertStereoToMonoS8Bit( AdapterC Data, int length ) | 301 static int convertStereoToMonoS8Bit( AdapterC Data, int length ) |
300 { | 302 { |
301 int i; | 303 int i; |
302 Sint8* buffer = (Sint8*) Data.buffer; | 304 Sint8* buffer = (Sint8*) Data.buffer; |
303 Sint8* src = (Sint8*) Data.buffer; | 305 Sint8* src = (Sint8*) Data.buffer; |
304 length >>= 1; | 306 length >>= 1; |
305 for( i = 0; i < length; i++ ) | 307 for( i = 0; i < length; i++, src+=2 ) |
306 buffer[i] = ((int) *(src++) + *(src++) ) >> 1; | 308 buffer[i] = ((int) src[0] + src[1] ) >> 1; |
307 return length; | 309 return length; |
308 } | 310 } |
309 | 311 |
310 static int convertStereoToMonoU8Bit( AdapterC Data, int length ) | 312 static int convertStereoToMonoU8Bit( AdapterC Data, int length ) |
311 { | 313 { |
312 int i; | 314 int i; |
313 Uint8* buffer = (Uint8*) Data.buffer; | 315 Uint8* buffer = (Uint8*) Data.buffer; |
314 Uint8* src = (Uint8*) Data.buffer; | 316 Uint8* src = (Uint8*) Data.buffer; |
315 length >>= 1; | 317 length >>= 1; |
316 for( i = 0; i < length; i++ ) | 318 for( i = 0; i < length; i++, src+=2 ) |
317 buffer[i] = ((int) *(src++) + *(src++) ) >> 1; | 319 buffer[i] = ((int) src[0] + src[1] ) >> 1; |
318 return length; | 320 return length; |
319 } | 321 } |
320 | 322 |
321 /*-------------------------------------------------------------------------*/ | 323 /*-------------------------------------------------------------------------*/ |
322 static int convertMonoToStereo16Bit( AdapterC Data, int length ) | 324 static int convertMonoToStereo16Bit( AdapterC Data, int length ) |
323 { | 325 { |
324 int i; | 326 int i; |
325 Uint16* buffer = (Uint16*) Data.buffer; | 327 Uint16* buffer = (Uint16*) Data.buffer; |
326 Uint16* dst = (Uint16*)Data.buffer + length; | 328 Uint16* dst = (Uint16*)Data.buffer + length; |
327 for( i = length>>1; i--; ) | 329 for( i = length>>1; i--; dst-=2 ) |
328 *(--dst) = *(--dst) = buffer[i]; | 330 dst[-1] = dst[-2] = buffer[i]; |
329 return 2*length; | 331 return 2*length; |
330 } | 332 } |
331 | 333 |
332 static int convertMonoToStereo8Bit( AdapterC Data, int length ) | 334 static int convertMonoToStereo8Bit( AdapterC Data, int length ) |
333 { | 335 { |
334 int i; | 336 int i; |
335 Uint8* buffer = Data.buffer; | 337 Uint8* buffer = Data.buffer; |
336 Uint8* dst = Data.buffer + 2*length; | 338 Uint8* dst = Data.buffer + 2*length; |
337 for( i = length; i--; ) | 339 for( i = length; i--; dst-=2 ) |
338 *(--dst) = *(--dst) = buffer[i]; | 340 dst[-1] = dst[-2] = buffer[i]; |
339 return 2*length; | 341 return 2*length; |
340 } | 342 } |
341 | 343 |
342 /*-------------------------------------------------------------------------*/ | 344 /*-------------------------------------------------------------------------*/ |
343 static int minus5dB( AdapterC Data, int length ) | 345 static int minus5dB( AdapterC Data, int length ) |
348 buffer[i]= 38084 * buffer[i] >> 16; | 350 buffer[i]= 38084 * buffer[i] >> 16; |
349 return length; | 351 return length; |
350 } | 352 } |
351 | 353 |
352 /*-------------------------------------------------------------------------*/ | 354 /*-------------------------------------------------------------------------*/ |
353 enum RateConverterType { varRate = 0, hlfRate = 1, dblRate = 2 }; | 355 enum RateConverterType{ |
356 dcrsRate = 0, | |
357 incrsRate = 1, | |
358 hlfRate = 2, | |
359 dblRate = 3 | |
360 }; | |
361 | |
354 static void initRateConverterBuffer( RateConverterBuffer *rcb, | 362 static void initRateConverterBuffer( RateConverterBuffer *rcb, |
355 AdapterC* Data, int length, enum RateConverterType r, int rel_size ) | 363 AdapterC* Data, int length, enum RateConverterType typ ) |
356 { | 364 { |
357 int size, dir; | 365 int size, minsize, dir; |
358 int den[] = { 0, 1, 2}; | 366 int den[] = { 0, 0, 1, 2}; |
359 int num[] = { 0, 2, 1}; | 367 int num[] = { 0, 0, 2, 1}; |
360 int i; | 368 int i; |
361 | 369 |
362 den[0] = Data->filter->denominator; | 370 den[incrsRate] = Data->filter->denominator; |
363 num[0] = Data->filter->numerator; | 371 num[incrsRate] = Data->filter->numerator; |
364 | 372 |
365 size = 2 * _fsize * abs(rel_size); | 373 size = 8 * _fsize; |
366 dir = rel_size > 0 ? 1 : 0; | 374 dir = typ&1; |
367 length >>= 1; | 375 length >>= 1; |
376 minsize = min( length, size ); | |
368 | 377 |
369 rcb->buffer = (Sint16*)( Data->buffer ); | 378 rcb->buffer = (Sint16*)( Data->buffer ); |
370 | 379 |
371 if( Data->mode & SDL_AI_Loop ) | 380 if( Data->mode & SDL_AI_Loop ) |
372 { | 381 { |
377 rcb->inbuffer[i] = rcb->buffer[length-size+i]; | 386 rcb->inbuffer[i] = rcb->buffer[length-size+i]; |
378 rcb->inbuffer[i+size] = rcb->buffer[i]; | 387 rcb->inbuffer[i+size] = rcb->buffer[i]; |
379 } | 388 } |
380 rcb->finp = rcb->linp = rcb->inbuffer + size; | 389 rcb->finp = rcb->linp = rcb->inbuffer + size; |
381 if( size < 0 ) | 390 if( size < 0 ) |
382 rcb->buffer += num[r] * ( length + 2 * size ) / den[r]; | 391 rcb->buffer += num[typ] * ( length + 2 * size ) / den[typ]; |
383 } | 392 } |
384 else | 393 else |
385 { | 394 { |
395 for( i = 0; i < minsize; i++ ) | |
396 { | |
397 rcb->inbuffer[i] = rcb->buffer[length-size+i]; | |
398 rcb->inbuffer[i+size] = 0; | |
399 rcb->inbuffer[i+2*size] = rcb->buffer[i]; | |
400 } | |
386 for( i = 0; i < size; i++ ) | 401 for( i = 0; i < size; i++ ) |
387 { | 402 { |
388 int k; | 403 rcb->inbuffer[i] = 0; |
389 k = length-size+i; | |
390 rcb->inbuffer[i] = k < 0 ? 0 : rcb->buffer[k]; | |
391 rcb->inbuffer[i+size] = 0; | 404 rcb->inbuffer[i+size] = 0; |
392 rcb->inbuffer[i+2*size] = i < length ? rcb->buffer[i] : 0; | 405 rcb->inbuffer[i+2*size] = 0; |
393 } | 406 } |
394 // !!!FIXME: take lenght < size into account | 407 rcb->flength = rcb->llength = size/2 + minsize/2; |
395 rcb->flength = rcb->llength = size; | 408 rcb->clength = length - minsize; |
396 rcb->clength = length - size; | |
397 | 409 |
398 if( dir ) | 410 if( dir ) |
399 { | 411 { |
400 rcb->finp = rcb->inbuffer + 5*size/2; | 412 rcb->finp = rcb->inbuffer + 2 * size + minsize/2; |
401 rcb->cinp = rcb->buffer + length - size/2; | 413 rcb->cinp = rcb->buffer + length - minsize/2; |
402 rcb->linp = rcb->inbuffer + 3*size/2; | 414 rcb->linp = rcb->inbuffer + size + minsize/2; |
403 rcb->buffer += den[r] * ( length + size ) / num[r]; | 415 rcb->buffer += den[typ] * ( length + minsize ) / num[typ]; |
404 } | 416 } |
405 else | 417 else |
406 { | 418 { |
407 rcb->finp = rcb->inbuffer + size/2; | 419 rcb->finp = rcb->inbuffer + size/2; |
408 rcb->cinp = rcb->buffer + size/2; | 420 rcb->cinp = rcb->buffer + size/2; |
433 return 2 * abs( rcb->buffer - outp ); | 445 return 2 * abs( rcb->buffer - outp ); |
434 } | 446 } |
435 | 447 |
436 | 448 |
437 /*-------------------------------------------------------------------------*/ | 449 /*-------------------------------------------------------------------------*/ |
450 /* | |
451 * !!! FIXME !!! | |
452 * | |
453 * The doubleRate filter is half as large as the halfRate one! Frank | |
454 */ | |
455 | |
456 | |
438 static int doubleRateMono( AdapterC Data, int length ) | 457 static int doubleRateMono( AdapterC Data, int length ) |
439 { | 458 { |
440 RateConverterBuffer rcb; | 459 RateConverterBuffer rcb; |
441 initRateConverterBuffer( &rcb, &Data, length, dblRate, 1 ); | 460 initRateConverterBuffer( &rcb, &Data, length, dblRate ); |
442 return doRateConversion( &rcb, doubleRate1, NULL ); | 461 return doRateConversion( &rcb, doubleRate1, NULL ); |
443 } | 462 } |
444 | 463 |
445 static int doubleRateStereo( AdapterC Data, int length ) | 464 static int doubleRateStereo( AdapterC Data, int length ) |
446 { | 465 { |
447 RateConverterBuffer rcb; | 466 RateConverterBuffer rcb; |
448 initRateConverterBuffer( &rcb, &Data, length, dblRate, 2 ); | 467 initRateConverterBuffer( &rcb, &Data, length, dblRate ); |
449 doRateConversion( &rcb, doubleRate2, NULL ); | 468 doRateConversion( &rcb, doubleRate2, NULL ); |
450 nextRateConverterBuffer( &rcb ); | 469 nextRateConverterBuffer( &rcb ); |
451 return 2 + doRateConversion( &rcb, doubleRate2, NULL ); | 470 return 2 + doRateConversion( &rcb, doubleRate2, NULL ); |
452 } | 471 } |
453 | 472 |
454 /*-------------------------------------------------------------------------*/ | 473 /*-------------------------------------------------------------------------*/ |
455 static int halfRateMono( AdapterC Data, int length ) | 474 static int halfRateMono( AdapterC Data, int length ) |
456 { | 475 { |
457 RateConverterBuffer rcb; | 476 RateConverterBuffer rcb; |
458 initRateConverterBuffer( &rcb, &Data, length, hlfRate, -1 ); | 477 initRateConverterBuffer( &rcb, &Data, length, hlfRate ); |
459 return doRateConversion( &rcb, halfRate1, NULL ); | 478 return doRateConversion( &rcb, halfRate1, NULL ); |
460 } | 479 } |
461 | 480 |
462 static int halfRateStereo( AdapterC Data, int length ) | 481 static int halfRateStereo( AdapterC Data, int length ) |
463 { | 482 { |
464 RateConverterBuffer rcb; | 483 RateConverterBuffer rcb; |
465 initRateConverterBuffer( &rcb, &Data, length, hlfRate, -2 ); | 484 initRateConverterBuffer( &rcb, &Data, length, hlfRate ); |
466 doRateConversion( &rcb, halfRate2, NULL ); | 485 doRateConversion( &rcb, halfRate2, NULL ); |
467 nextRateConverterBuffer( &rcb ); | 486 nextRateConverterBuffer( &rcb ); |
468 return 2 + doRateConversion( &rcb, halfRate2, NULL ); | 487 return 2 + doRateConversion( &rcb, halfRate2, NULL ); |
469 } | 488 } |
470 | 489 |
471 /*-------------------------------------------------------------------------*/ | 490 /*-------------------------------------------------------------------------*/ |
472 static int increaseRateMono( AdapterC Data, int length ) | 491 static int increaseRateMono( AdapterC Data, int length ) |
473 { | 492 { |
474 RateConverterBuffer rcb; | 493 RateConverterBuffer rcb; |
475 initRateConverterBuffer( &rcb, &Data, length, varRate, 2 ); | 494 initRateConverterBuffer( &rcb, &Data, length, incrsRate ); |
476 return doRateConversion( &rcb, increaseRate1, Data.filter ); | 495 return doRateConversion( &rcb, increaseRate1, Data.filter ); |
477 } | 496 } |
478 | 497 |
479 static int increaseRateStereo( AdapterC Data, int length ) | 498 static int increaseRateStereo( AdapterC Data, int length ) |
480 { | 499 { |
481 RateConverterBuffer rcb; | 500 RateConverterBuffer rcb; |
482 initRateConverterBuffer( &rcb, &Data, length, varRate, 4 ); | 501 initRateConverterBuffer( &rcb, &Data, length, incrsRate ); |
483 doRateConversion( &rcb, increaseRate2, Data.filter ); | 502 doRateConversion( &rcb, increaseRate2, Data.filter ); |
484 nextRateConverterBuffer( &rcb ); | 503 nextRateConverterBuffer( &rcb ); |
485 return 2 + doRateConversion( &rcb, increaseRate2, Data.filter ); | 504 return 2 + doRateConversion( &rcb, increaseRate2, Data.filter ); |
486 } | 505 } |
487 | 506 |
488 /*-------------------------------------------------------------------------*/ | 507 /*-------------------------------------------------------------------------*/ |
489 static int decreaseRateMono( AdapterC Data, int length ) | 508 static int decreaseRateMono( AdapterC Data, int length ) |
490 { | 509 { |
491 RateConverterBuffer rcb; | 510 RateConverterBuffer rcb; |
492 initRateConverterBuffer( &rcb, &Data, length, varRate, -2 ); | 511 initRateConverterBuffer( &rcb, &Data, length, dcrsRate ); |
493 return doRateConversion( &rcb, decreaseRate1, Data.filter ); | 512 return doRateConversion( &rcb, decreaseRate1, Data.filter ); |
494 } | 513 } |
495 | 514 |
496 static int decreaseRateStereo( AdapterC Data, int length ) | 515 static int decreaseRateStereo( AdapterC Data, int length ) |
497 { | 516 { |
498 RateConverterBuffer rcb; | 517 RateConverterBuffer rcb; |
499 initRateConverterBuffer( &rcb, &Data, length, varRate, -4 ); | 518 initRateConverterBuffer( &rcb, &Data, length, dcrsRate ); |
500 doRateConversion( &rcb, decreaseRate2, Data.filter ); | 519 doRateConversion( &rcb, decreaseRate2, Data.filter ); |
501 nextRateConverterBuffer( &rcb ); | 520 nextRateConverterBuffer( &rcb ); |
502 return doRateConversion( &rcb, decreaseRate2, Data.filter ); | 521 return doRateConversion( &rcb, decreaseRate2, Data.filter ); |
503 } | 522 } |
504 | 523 |
530 8, 11, 13, 14, 16, -1, /* /15 */ | 549 8, 11, 13, 14, 16, -1, /* /15 */ |
531 9, 11, 13, 15 }; /* /16 */ | 550 9, 11, 13, 15 }; /* /16 */ |
532 | 551 |
533 | 552 |
534 Fraction Result = {0,0}; | 553 Fraction Result = {0,0}; |
535 int n,num=1,den=1; | 554 int i,num,den=1; |
536 | 555 |
537 float RelErr, BestErr = 0; | 556 float RelErr, BestErr = 0; |
538 if( Value < 31/64. || Value > 64/31. ) return Result; | 557 if( Value < 31/64. || Value > 64/31. ) return Result; |
539 | 558 |
540 for( n = 0; n < SDL_TABLESIZE(frac); num=frac[n++] ) | 559 for( i = 0; i < SDL_TABLESIZE(frac); i++ ) |
541 { | 560 { |
561 num = frac[i]; | |
542 if( num < 0 ) den++; | 562 if( num < 0 ) den++; |
543 RelErr = Value * num / den; | 563 RelErr = Value * num / den; |
544 RelErr = min( RelErr, 1/RelErr ); | 564 RelErr = min( RelErr, 1/RelErr ); |
545 if( RelErr > BestErr ) | 565 if( RelErr > BestErr ) |
546 { | 566 { |
582 dst[i] = w * sinc( omega * (i+phase) ); | 602 dst[i] = w * sinc( omega * (i+phase) ); |
583 dst[127-i] = w * sinc( omega * (127-i+phase) ); | 603 dst[127-i] = w * sinc( omega * (127-i+phase) ); |
584 } | 604 } |
585 } | 605 } |
586 | 606 |
587 typedef struct{ | 607 static void setupVarFilter( VarFilter* filter, float Ratio ) |
588 float scale; | 608 { |
589 int incr; | 609 int i,n,d, incr, phase = 0; |
590 } VarFilterMode; | 610 float Scale, rd; |
591 | |
592 const VarFilterMode Up = { 0.0211952, -1 }; | |
593 const VarFilterMode Down = { 0.0364733, 1 }; | |
594 | |
595 static void setupVarFilter( VarFilter* filter, | |
596 float Ratio, VarFilterMode Direction ) | |
597 { | |
598 int i,n,d; | |
599 Fraction IRatio; | 611 Fraction IRatio; |
600 float phase = 0.; | 612 |
601 IRatio = findFraction( Ratio ); | 613 IRatio = findFraction( Ratio ); |
614 Scale = Ratio < 1. ? 0.0364733 : 0.0211952; | |
602 Ratio = min( Ratio, 1/Ratio ); | 615 Ratio = min( Ratio, 1/Ratio ); |
603 | 616 |
604 n = IRatio.numerator; | 617 n = IRatio.numerator; |
605 d = IRatio.denominator; | 618 d = IRatio.denominator; |
606 filter->denominator = d; | 619 filter->denominator = d; |
607 filter->numerator = n; | 620 filter->numerator = n; |
621 rd = 1. / d; | |
608 | 622 |
609 for( i = 0; i < d; i++ ) | 623 for( i = 0; i < d; i++ ) |
610 { | 624 { |
611 if( phase >= n ) | 625 calculateVarFilter( filter->c[i], Ratio, phase*rd, Scale ); |
612 { | 626 phase += n; |
613 phase -= d; | 627 filter->incr[i] = phase / d; |
614 filter->incr[i] = abs(Direction.incr); | 628 phase %= d; |
615 } | |
616 else | |
617 filter->incr[i] = abs(1+Direction.incr); | |
618 | |
619 calculateVarFilter( filter->c[i], Ratio, phase/(float)n, | |
620 Direction.scale ); | |
621 phase += d; | |
622 } | 629 } |
623 } | 630 } |
624 | 631 |
625 /*-------------------------------------------------------------------------*/ | 632 /*-------------------------------------------------------------------------*/ |
626 static void createRateConverter( Sound_AudioCVT *Data, int* fip, | 633 static void createRateConverter( Sound_AudioCVT *Data, int* fip, |
646 while( Ratio > 64./31.) | 653 while( Ratio > 64./31.) |
647 { | 654 { |
648 Data->adapter[filter_index++] = | 655 Data->adapter[filter_index++] = |
649 Mono ? doubleRateMono : doubleRateStereo; | 656 Mono ? doubleRateMono : doubleRateStereo; |
650 Ratio /= 2.; | 657 Ratio /= 2.; |
651 Data->len_mult *= 2; | 658 Data->mult *= 2; |
652 Data->add *= 2; | 659 Data->add *= 2; |
653 Data->add += _fsize; | 660 Data->add += _fsize; |
654 } | 661 } |
655 | 662 |
656 while( Ratio < 31./64. ) | 663 while( Ratio < 31./64. ) |
660 Ratio *= 2; | 667 Ratio *= 2; |
661 } | 668 } |
662 | 669 |
663 if( Ratio > 1. ) | 670 if( Ratio > 1. ) |
664 { | 671 { |
665 setupVarFilter( &Data->filter, Ratio, Up ); | 672 setupVarFilter( &Data->filter, Ratio ); |
666 Data->adapter[VarPos] = | 673 Data->adapter[VarPos] = |
667 Mono ? increaseRateMono : increaseRateStereo; | 674 Mono ? increaseRateMono : increaseRateStereo; |
668 Data->len_mult *= 2; | 675 Data->mult *= 2; |
669 Data->add *= 2; | 676 Data->add *= 2; |
670 Data->add += _fsize; | 677 Data->add += _fsize; |
671 } | 678 } |
672 else | 679 else |
673 { | 680 { |
674 setupVarFilter( &Data->filter, Ratio, Down ); | 681 setupVarFilter( &Data->filter, Ratio ); |
675 Data->adapter[filter_index++] = | 682 Data->adapter[filter_index++] = |
676 Mono ? decreaseRateMono : decreaseRateStereo; | 683 Mono ? decreaseRateMono : decreaseRateStereo; |
677 } | 684 } |
678 *fip = filter_index; | 685 *fip = filter_index; |
679 } | 686 } |
685 int filter_index = *fip; | 692 int filter_index = *fip; |
686 | 693 |
687 if( src.channels == 2 && dst.channels == 1 ) | 694 if( src.channels == 2 && dst.channels == 1 ) |
688 { | 695 { |
689 Data->add /= 2; | 696 Data->add /= 2; |
690 Data->len_mult /= 2; | 697 Data->mult /= 2; |
691 | 698 |
692 if( !IS_SYSENDIAN(src) ) | 699 if( !IS_SYSENDIAN(src) ) |
693 Data->adapter[filter_index++] = swapBytes; | 700 Data->adapter[filter_index++] = swapBytes; |
694 | 701 |
695 if( IS_SIGNED(src) ) | 702 if( IS_SIGNED(src) ) |
712 } | 719 } |
713 | 720 |
714 if( src.channels == 1 && dst.channels == 2 ) | 721 if( src.channels == 1 && dst.channels == 2 ) |
715 { | 722 { |
716 Data->add *= 2; | 723 Data->add *= 2; |
717 Data->len_mult *= 2; | 724 Data->mult *= 2; |
718 Data->adapter[filter_index++] = convertMonoToStereo16Bit; | 725 Data->adapter[filter_index++] = convertMonoToStereo16Bit; |
719 } | 726 } |
720 | 727 |
721 *fip = filter_index; | 728 *fip = filter_index; |
722 } | 729 } |
727 { | 734 { |
728 int filter_index = *fip; | 735 int filter_index = *fip; |
729 if( IS_16BIT(src) ) | 736 if( IS_16BIT(src) ) |
730 { | 737 { |
731 Data->add /= 2; | 738 Data->add /= 2; |
732 Data->len_mult /= 2; | 739 Data->mult /= 2; |
733 | 740 |
734 if( IS_SYSENDIAN(src) ) | 741 if( IS_SYSENDIAN(src) ) |
735 Data->adapter[filter_index++] = cut16BitSysTo8Bit; | 742 Data->adapter[filter_index++] = cut16BitSysTo8Bit; |
736 else | 743 else |
737 Data->adapter[filter_index++] = cut16BitWrongTo8Bit; | 744 Data->adapter[filter_index++] = cut16BitWrongTo8Bit; |
738 } | 745 } |
739 | 746 |
740 if( src.channels == 2 && dst.channels == 1 ) | 747 if( src.channels == 2 && dst.channels == 1 ) |
741 { | 748 { |
742 Data->add /= 2; | 749 Data->add /= 2; |
743 Data->len_mult /= 2; | 750 Data->mult /= 2; |
744 | 751 |
745 if( IS_SIGNED(src) ) | 752 if( IS_SIGNED(src) ) |
746 Data->adapter[filter_index++] = convertStereoToMonoS8Bit; | 753 Data->adapter[filter_index++] = convertStereoToMonoS8Bit; |
747 else | 754 else |
748 Data->adapter[filter_index++] = convertStereoToMonoU8Bit; | 755 Data->adapter[filter_index++] = convertStereoToMonoU8Bit; |
752 Data->adapter[filter_index++] = changeSigned8Bit; | 759 Data->adapter[filter_index++] = changeSigned8Bit; |
753 | 760 |
754 if( src.channels == 1 && dst.channels == 2 ) | 761 if( src.channels == 1 && dst.channels == 2 ) |
755 { | 762 { |
756 Data->add *= 2; | 763 Data->add *= 2; |
757 Data->len_mult *= 2; | 764 Data->mult *= 2; |
758 Data->adapter[filter_index++] = convertMonoToStereo8Bit; | 765 Data->adapter[filter_index++] = convertMonoToStereo8Bit; |
759 } | 766 } |
760 | 767 |
761 if( !IS_8BIT(dst) ) | 768 if( !IS_8BIT(dst) ) |
762 { | 769 { |
763 Data->add *= 2; | 770 Data->add *= 2; |
764 Data->len_mult *= 2; | 771 Data->mult *= 2; |
765 if( IS_SYSENDIAN(dst) ) | 772 if( IS_SYSENDIAN(dst) ) |
766 Data->adapter[filter_index++] = expand8BitTo16BitSys; | 773 Data->adapter[filter_index++] = expand8BitTo16BitSys; |
767 else | 774 else |
768 Data->adapter[filter_index++] = expand8BitTo16BitWrong; | 775 Data->adapter[filter_index++] = expand8BitTo16BitWrong; |
769 } | 776 } |
778 int filter_index = *fip; | 785 int filter_index = *fip; |
779 | 786 |
780 if( IS_FLOAT(src) ) | 787 if( IS_FLOAT(src) ) |
781 { | 788 { |
782 Data->adapter[filter_index++] = cutFloatTo16Bit; | 789 Data->adapter[filter_index++] = cutFloatTo16Bit; |
783 Data->len_mult /= 2; | 790 Data->mult /= 2; |
784 Data->add /= 2; | 791 Data->add /= 2; |
785 } | 792 } |
786 | 793 |
787 if( IS_8BIT(src) || IS_8BIT(dst) ) | 794 if( IS_8BIT(src) || IS_8BIT(dst) ) |
788 createFormatConverter8Bit( Data, &filter_index, src, dst); | 795 createFormatConverter8Bit( Data, &filter_index, src, dst); |
790 createFormatConverter16Bit( Data, &filter_index, src, dst); | 797 createFormatConverter16Bit( Data, &filter_index, src, dst); |
791 | 798 |
792 if( IS_FLOAT(dst) ) | 799 if( IS_FLOAT(dst) ) |
793 { | 800 { |
794 Data->adapter[filter_index++] = expand16BitToFloat; | 801 Data->adapter[filter_index++] = expand16BitToFloat; |
795 Data->len_mult *= 2; | 802 Data->mult *= 2; |
796 Data->add *= 2; | 803 Data->add *= 2; |
797 } | 804 } |
798 | 805 |
799 *fip = filter_index; | 806 *fip = filter_index; |
800 } | 807 } |
806 { | 813 { |
807 SDL_AudioSpec intrm; | 814 SDL_AudioSpec intrm; |
808 int filter_index = 0; | 815 int filter_index = 0; |
809 | 816 |
810 if( Data == NULL ) return -1; | 817 if( Data == NULL ) return -1; |
811 Data->len_mult = 1.; | 818 Data->mult = 1.; |
812 Data->add = 0; | 819 Data->add = 0; |
820 Data->filter.denominator = 0; | |
813 | 821 |
814 /* Check channels */ | 822 /* Check channels */ |
815 if( src.channels < 1 || src.channels > 2 || | 823 if( src.channels < 1 || src.channels > 2 || |
816 dst.channels < 1 || dst.channels > 2 ) goto error_exit; | 824 dst.channels < 1 || dst.channels > 2 ) goto error_exit; |
817 | 825 |
838 /* Convert to final format */ | 846 /* Convert to final format */ |
839 createFormatConverter( Data, &filter_index, intrm, dst ); | 847 createFormatConverter( Data, &filter_index, intrm, dst ); |
840 | 848 |
841 /* Set up the filter information */ | 849 /* Set up the filter information */ |
842 sucess_exit: | 850 sucess_exit: |
843 if( filter_index > 0 ) | |
844 Data->needed = 1; | |
845 /* !!! FIXME: Is it okay to assign NULL to a function pointer? | 851 /* !!! FIXME: Is it okay to assign NULL to a function pointer? |
846 Borland says no. -frank */ | 852 Borland says no. -frank */ |
847 Data->adapter[filter_index] = NULL; | 853 Data->adapter[filter_index] = NULL; |
854 Data->needed = filter_index > 0 ? 1 : 0; | |
848 return 0; | 855 return 0; |
849 | 856 |
850 error_exit: | 857 error_exit: |
851 /* !!! FIXME: Is it okay to assign NULL to a function pointer? | 858 /* !!! FIXME: Is it okay to assign NULL to a function pointer? |
852 Borland says no. -frank */ | 859 Borland says no. -frank */ |
853 Data->adapter[0] = NULL; | 860 Data->adapter[0] = NULL; |
861 Data->needed = 0; | |
854 return -1; | 862 return -1; |
855 } | 863 } |
856 | 864 |
857 /*-------------------------------------------------------------------------*/ | 865 /*-------------------------------------------------------------------------*/ |
858 static char *fmt_to_str(Uint16 fmt) | 866 static char *fmt_to_str(Uint16 fmt) |
910 for( j = 0; j < SDL_TABLESIZE(AdapterDescription); j++ ) | 918 for( j = 0; j < SDL_TABLESIZE(AdapterDescription); j++ ) |
911 { | 919 { |
912 if( Data->adapter[i] == AdapterDescription[j].adapter ) | 920 if( Data->adapter[i] == AdapterDescription[j].adapter ) |
913 { | 921 { |
914 fprintf( stderr, " %s\n", AdapterDescription[j].name ); | 922 fprintf( stderr, " %s\n", AdapterDescription[j].name ); |
915 if( Data->adapter[i] == NULL ) return; | 923 if( Data->adapter[i] == NULL ) goto sucess_exit; |
916 goto cont; | 924 goto cont; |
917 } | 925 } |
918 } | 926 } |
919 fprintf( stderr, " Error: unknown adapter\n" ); | 927 fprintf( stderr, " Error: unknown adapter\n" ); |
928 | |
920 cont: | 929 cont: |
921 } | 930 } |
922 fprintf( stderr, " Error: NULL adapter missing\n" ); | 931 fprintf( stderr, " Error: NULL adapter missing\n" ); |
932 sucess_exit: | |
933 if( Data->filter.denominator ) | |
934 { | |
935 fprintf( stderr, "Variable Rate Converter:\n" | |
936 "numerator: %3d, denominator: %3d\n", | |
937 Data->filter.denominator, Data->filter.numerator ); | |
938 | |
939 fprintf( stderr, "increment sequence: " ); | |
940 for( i = 0; i < Data->filter.denominator; i++ ) | |
941 fprintf( stderr, "%3d ", Data->filter.incr[i] ); | |
942 | |
943 fprintf( stderr, "\n" ); | |
944 } | |
945 else | |
946 { | |
947 fprintf( stderr, "No Variable Rate Converter\n" ); | |
948 } | |
923 } | 949 } |
924 | 950 |
925 | 951 |
926 int Sound_BuildAudioCVT(Sound_AudioCVT *Data, | 952 int Sound_BuildAudioCVT(Sound_AudioCVT *Data, |
927 Uint16 src_format, Uint8 src_channels, int src_rate, | 953 Uint16 src_format, Uint8 src_channels, int src_rate, |
947 dst.format = dst_format; | 973 dst.format = dst_format; |
948 dst.channels = dst_channels; | 974 dst.channels = dst_channels; |
949 dst.freq = dst_rate; | 975 dst.freq = dst_rate; |
950 | 976 |
951 ret = BuildAudioCVT( Data, src, dst ); | 977 ret = BuildAudioCVT( Data, src, dst ); |
978 Data->len_mult = Data->mult > 1 ? ceil(Data->mult) : 1; | |
979 Data->len_ratio = Data->mult; | |
952 | 980 |
953 show_AudioCVT( Data ); | 981 show_AudioCVT( Data ); |
954 fprintf (stderr, "\n" | 982 fprintf (stderr, "\n" |
955 "return value: %d \n", ret ); | 983 "return value: %d \n", ret ); |
956 | 984 |