comparison imgresample.c @ 2082:3dc9bbe1b152 libavcodec

polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
author michael
date Thu, 17 Jun 2004 15:43:23 +0000
parents b77fe059dd09
children 17ec73c65748
comparison
equal deleted inserted replaced
2081:d3015863f745 2082:3dc9bbe1b152
52 int h_incr, v_incr; 52 int h_incr, v_incr;
53 int16_t h_filters[NB_PHASES][NB_TAPS] __align8; /* horizontal filters */ 53 int16_t h_filters[NB_PHASES][NB_TAPS] __align8; /* horizontal filters */
54 int16_t v_filters[NB_PHASES][NB_TAPS] __align8; /* vertical filters */ 54 int16_t v_filters[NB_PHASES][NB_TAPS] __align8; /* vertical filters */
55 uint8_t *line_buf; 55 uint8_t *line_buf;
56 }; 56 };
57
58 void av_build_filter(int16_t *filter, double factor, int tap_count, int phase_count, int scale, int type);
57 59
58 static inline int get_phase(int pos) 60 static inline int get_phase(int pos)
59 { 61 {
60 return ((pos) >> (POS_FRAC_BITS - PHASE_BITS)) & ((1 << PHASE_BITS) - 1); 62 return ((pos) >> (POS_FRAC_BITS - PHASE_BITS)) & ((1 << PHASE_BITS) - 1);
61 } 63 }
538 540
539 output += owrap; 541 output += owrap;
540 } 542 }
541 } 543 }
542 544
543 /* XXX: the following filter is quite naive, but it seems to suffice
544 for 4 taps */
545 static void build_filter(int16_t *filter, float factor)
546 {
547 int ph, i, v;
548 float x, y, tab[NB_TAPS], norm, mult, target;
549
550 /* if upsampling, only need to interpolate, no filter */
551 if (factor > 1.0)
552 factor = 1.0;
553
554 for(ph=0;ph<NB_PHASES;ph++) {
555 norm = 0;
556 for(i=0;i<NB_TAPS;i++) {
557 #if 1
558 const float d= -0.5; //first order derivative = -0.5
559 x = fabs(((float)(i - FCENTER) - (float)ph / NB_PHASES) * factor);
560 if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*( -x*x + x*x*x);
561 else y= d*(-4 + 8*x - 5*x*x + x*x*x);
562 #else
563 x = M_PI * ((float)(i - FCENTER) - (float)ph / NB_PHASES) * factor;
564 if (x == 0)
565 y = 1.0;
566 else
567 y = sin(x) / x;
568 #endif
569 tab[i] = y;
570 norm += y;
571 }
572
573 /* normalize so that an uniform color remains the same */
574 target= 1 << FILTER_BITS;
575 for(i=0;i<NB_TAPS;i++) {
576 mult = target / norm;
577 v = lrintf(tab[i] * mult);
578 filter[ph * NB_TAPS + i] = v;
579 norm -= tab[i];
580 target -= v;
581 }
582 }
583 }
584
585 ImgReSampleContext *img_resample_init(int owidth, int oheight, 545 ImgReSampleContext *img_resample_init(int owidth, int oheight,
586 int iwidth, int iheight) 546 int iwidth, int iheight)
587 { 547 {
588 return img_resample_full_init(owidth, oheight, iwidth, iheight, 548 return img_resample_full_init(owidth, oheight, iwidth, iheight,
589 0, 0, 0, 0, 0, 0, 0, 0); 549 0, 0, 0, 0, 0, 0, 0, 0);
624 s->pad_oheight = oheight - (padtop + padbottom); 584 s->pad_oheight = oheight - (padtop + padbottom);
625 585
626 s->h_incr = ((iwidth - leftBand - rightBand) * POS_FRAC) / s->pad_owidth; 586 s->h_incr = ((iwidth - leftBand - rightBand) * POS_FRAC) / s->pad_owidth;
627 s->v_incr = ((iheight - topBand - bottomBand) * POS_FRAC) / s->pad_oheight; 587 s->v_incr = ((iheight - topBand - bottomBand) * POS_FRAC) / s->pad_oheight;
628 588
629 build_filter(&s->h_filters[0][0], (float) s->pad_owidth / 589 av_build_filter(&s->h_filters[0][0], (float) s->pad_owidth /
630 (float) (iwidth - leftBand - rightBand)); 590 (float) (iwidth - leftBand - rightBand), NB_TAPS, NB_PHASES, 1<<FILTER_BITS, 0);
631 build_filter(&s->v_filters[0][0], (float) s->pad_oheight / 591 av_build_filter(&s->v_filters[0][0], (float) s->pad_oheight /
632 (float) (iheight - topBand - bottomBand)); 592 (float) (iheight - topBand - bottomBand), NB_TAPS, NB_PHASES, 1<<FILTER_BITS, 0);
633 593
634 return s; 594 return s;
635 fail: 595 fail:
636 av_free(s); 596 av_free(s);
637 return NULL; 597 return NULL;