int makeFilter(HWORD Imp[], HWORD ImpD[], UHWORD *LpScl, UHWORD Nwing, double Froll, double Beta) { double DCgain, Scl, Maxh; HWORD Dh; int i, temp; if (Nwing > MAXNWING) /* Check for valid parameters */ return(1); if ((Froll<=0) || (Froll>1)) return(2); if (Beta < 1) return(3); /* * Design Kaiser-windowed sinc-function low-pass filter */ LpFilter(ImpR, (int)Nwing, 0.5*Froll, Beta, Npc); /* Compute the DC gain of the lowpass filter, and its maximum coefficient * magnitude. Scale the coefficients so that the maximum coeffiecient just * fits in Nh-bit fixed-point, and compute LpScl as the NLpScl-bit (signed) * scale factor which when multiplied by the output of the lowpass filter * gives unity gain. */ DCgain = 0; Dh = Npc; /* Filter sampling period for factors>=1 */ for (i=Dh; i<Nwing; i+=Dh) DCgain += ImpR[i]; DCgain = 2*DCgain + ImpR[0]; /* DC gain of real coefficients */ for (Maxh=i=0; i<Nwing; i++) Maxh = MAX(Maxh, fabs(ImpR[i])); Scl = ((1<<(Nh-1))-1)/Maxh; /* Map largest coeff to 16-bit maximum */ temp = (int) fabs((1<<(NLpScl+Nh))/(DCgain*Scl)); if (temp >= 1<<16) return(4); /* Filter scale factor overflows UHWORD */ *LpScl = temp; /* Scale filter coefficients for Nh bits and convert to integer */ if (ImpR[0] < 0) /* Need pos 1st value for LpScl storage */ Scl = -Scl; for (i=0; i<Nwing; i++) /* Scale them */ ImpR[i] *= Scl; for (i=0; i<Nwing; i++) /* Round them */ Imp[i] = (int) (ImpR[i] + 0.5); /* ImpD makes linear interpolation of the filter coefficients faster */ for (i=0; i<Nwing-1; i++) ImpD[i] = Imp[i+1] - Imp[i]; ImpD[Nwing-1] = - Imp[Nwing-1]; /* Last coeff. not interpolated */ return(0); }
int makeFilter(Float Imp[], long Nwing, double Froll, double Beta, long Num, int Normalize) { double *ImpR; long Mwing, i; if (Nwing > MAXNWING) /* Check for valid parameters */ return(-1); if ((Froll<=0) || (Froll>1)) return(-2); /* it does help accuracy a bit to have the window stop at * a zero-crossing of the sinc function */ Mwing = (long)floor((double)Nwing/(((double)Num)/Froll))*(((double)Num)/Froll) +0.5; if (Mwing==0) return(-4); ImpR = (double *) malloc(sizeof(double) * Mwing); /* Design a Nuttall or Kaiser windowed Sinc low-pass filter */ LpFilter(ImpR, Mwing, Froll, Beta, Num); if (Normalize) { /* 'correct' the DC gain of the lowpass filter */ long Dh; double DCgain; DCgain = 0; Dh = Num; /* Filter sampling period for factors>=1 */ for (i=Dh; i<Mwing; i+=Dh) DCgain += ImpR[i]; DCgain = 2*DCgain + ImpR[0]; /* DC gain of real coefficients */ /*st_report("DCgain err=%.12f",DCgain-1.0);*/ DCgain = 1.0/DCgain; for (i=0; i<Mwing; i++) Imp[i] = ImpR[i]*DCgain; } else { for (i=0; i<Mwing; i++) Imp[i] = ImpR[i]; } free(ImpR); for (i=Mwing; i<=Nwing; i++) Imp[i] = 0; /* Imp[Mwing] and Imp[-1] needed for quadratic interpolation */ Imp[-1] = Imp[1]; return(Mwing); }