comparison libaf/af.c @ 14433:95bb94a930a3

always cancel down fractions (frac_t) to avoid overflows and playback problems (e.g. when using resample and equalizer filters together, see http://mplayerhq.hu/pipermail/mplayer-users/2004-December/050058.html)
author reimar
date Sat, 08 Jan 2005 21:34:06 +0000
parents 8380694ba14f
children 408dfb63ff95
comparison
equal deleted inserted replaced
14432:275b2ce30af7 14433:95bb94a930a3
522 int t = s->input.bps*s->input.nch; 522 int t = s->input.bps*s->input.nch;
523 af_instance_t* af=s->first; 523 af_instance_t* af=s->first;
524 register frac_t mul = {1,1}; 524 register frac_t mul = {1,1};
525 // Iterate through all filters 525 // Iterate through all filters
526 do{ 526 do{
527 mul.n *= af->mul.n; 527 af_frac_mul(&mul, &af->mul);
528 mul.d *= af->mul.d;
529 af=af->next; 528 af=af->next;
530 }while(af); 529 }while(af);
531 return t * (((len/t)*mul.n + 1)/mul.d); 530 return t * (((len/t)*mul.n + 1)/mul.d);
532 } 531 }
533 532
540 int t = s->input.bps*s->input.nch; 539 int t = s->input.bps*s->input.nch;
541 af_instance_t* af=s->first; 540 af_instance_t* af=s->first;
542 register frac_t mul = {1,1}; 541 register frac_t mul = {1,1};
543 // Iterate through all filters 542 // Iterate through all filters
544 do{ 543 do{
545 mul.n *= af->mul.n; 544 af_frac_mul(&mul, &af->mul);
546 mul.d *= af->mul.d;
547 af=af->next; 545 af=af->next;
548 }while(af); 546 }while(af);
549 return t * (((len/t) * mul.d - 1)/mul.n); 547 return t * (((len/t) * mul.d - 1)/mul.n);
550 } 548 }
551 549
565 int out = 0; 563 int out = 0;
566 af_instance_t* af=s->first; 564 af_instance_t* af=s->first;
567 register frac_t mul = {1,1}; 565 register frac_t mul = {1,1};
568 // Iterate through all filters and calculate total multiplication factor 566 // Iterate through all filters and calculate total multiplication factor
569 do{ 567 do{
570 mul.n *= af->mul.n; 568 af_frac_mul(&mul, &af->mul);
571 mul.d *= af->mul.d;
572 af=af->next; 569 af=af->next;
573 }while(af); 570 }while(af);
574 // Sanity check 571 // Sanity check
575 if(!mul.n || !mul.d) 572 if(!mul.n || !mul.d)
576 return -1; 573 return -1;
643 filt = filt->prev; 640 filt = filt->prev;
644 } 641 }
645 return NULL; 642 return NULL;
646 } 643 }
647 644
645 /**
646 * \brief calculate greatest common divisior of a and b.
647 * Extended for negative and 0 values. If both are 0 the result is 1.
648 * The sign of the result will be so that it has the same sign as b.
649 */
650 int af_gcd(register int a, register int b) {
651 int b_org = b;
652 while (b != 0) {
653 a %= b;
654 if (a == 0)
655 break;
656 b %= a;
657 }
658 // the result is either in a or b. As the other one is 0 just add them.
659 a += b;
660 if (!a)
661 return 1;
662 if (a * b_org < 0)
663 return -a;
664 return a;
665 }
666
667 /**
668 * \brief cancel down a fraction f
669 */
670 void af_frac_cancel(frac_t *f) {
671 int gcd = af_gcd(f->n, f->d);
672 f->n /= gcd;
673 f->d /= gcd;
674 }
675
676 /**
677 * \brief multiply out by in and store result in out.
678 * the resulting fraction wil be cancelled down
679 * if in and out were.
680 */
681 void af_frac_mul(frac_t *out, const frac_t *in) {
682 int gcd1 = af_gcd(out->n, in->d);
683 int gcd2 = af_gcd(in->n, out->d);
684 out->n = (out->n / gcd1) * (in->n / gcd2);
685 out->d = (out->d / gcd2) * (in->d / gcd1);
686 }
687
648 void af_help (void) { 688 void af_help (void) {
649 int i = 0; 689 int i = 0;
650 af_msg(AF_MSG_INFO, "Available audio filters:\n"); 690 af_msg(AF_MSG_INFO, "Available audio filters:\n");
651 while (filter_list[i]) { 691 while (filter_list[i]) {
652 if (filter_list[i]->comment && filter_list[i]->comment[0]) 692 if (filter_list[i]->comment && filter_list[i]->comment[0])