diff options
author | Benny Prijono <bennylp@teluu.com> | 2007-04-07 14:53:15 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2007-04-07 14:53:15 +0000 |
commit | ca07a9833149d270d1e5b44cfa381ac6ac03e39c (patch) | |
tree | 0d1297c8326f76aec00e068795ed1505047c63a7 /third_party/resample/src/windowfilter.c | |
parent | 81d1b2797aa3945c529d57f9ddf6179ec2b392a4 (diff) |
Moved resample to third_party directory
git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/split-3rd-party@1170 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'third_party/resample/src/windowfilter.c')
-rw-r--r-- | third_party/resample/src/windowfilter.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/third_party/resample/src/windowfilter.c b/third_party/resample/src/windowfilter.c new file mode 100644 index 00000000..b2b67690 --- /dev/null +++ b/third_party/resample/src/windowfilter.c @@ -0,0 +1,114 @@ +/* makefilter.c */ + +#include <stdio.h> +#include <math.h> +#include "stdefs.h" +#include "filterkit.h" +#include "resample.h" +#define MAXNWING 8192 /* FIXME: flush */ + +/* LIBRARIES needed: + * + * 1. filterkit + * makeFilter() - designs a Kaiser-windowed low-pass filter + * writeFilter() - writes a filter to a standard filter file + * GetUShort() - prompt user for a UHWORD with help + * GetDouble() - prompt user for a double with help + * + * 2. math + */ + +char NmultHelp[] = + "\n Nmult is the length of the symmetric FIR lowpass filter used" + "\n by the sampling rate converter. It must be odd." + "\n This is the number of multiplies per output sample for" + "\n up-conversions (Factor>1), and is the number of multiplies" + "\n per input sample for down-conversions (Factor<1). Thus if" + "\n the rate conversion is Srate2 = Factor*Srate1, then you have" + "\n Nmult*Srate1*MAXof(Factor,1) multiplies per second of real time." + "\n Naturally, higher Nmult gives better lowpass-filtering at the" + "\n expense of longer compute times. Nmult should be odd because" + "\n it is the length of a symmetric FIR filter, and the current" + "\n implementation requires a coefficient at the time origin.\n"; + +char FrollHelp[] = + "\n Froll determines the frequency at which the lowpass filter begins to" + "\n roll-off. If Froll=1, then there is no 'guard zone' and the filter" + "\n roll-off region will be aliased. If Froll is 0.90, for example, then" + "\n the filter begins rolling off at 0.90*Srate/2, so that by Srate/2," + "\n the filter is well down and aliasing is reduced. Since aliasing" + "\n distortion is typically worse than loss of the high-frequency spectral" + "\n amplitude, Froll<1 is highly recommended. The default of 0.90" + "\n sacrifices the upper 10 percent of the spectrum as an anti-aliasing" + "\n guard zone.\n"; + +char BetaHelp[] = + "\n Beta trades the rejection of the lowpass filter against the" + "\n transition width from passband to stopband. Larger Beta means" + "\n a slower transition and greater stopband rejection. See Rabiner" + "\n and Gold (Th. and App. of DSP) under Kaiser windows for more about" + "\n Beta. The following table from Rabiner and Gold (p. 101) gives some" + "\n feel for the effect of Beta:" + "\n" + "\n BETA D PB RIP SB RIP" + "\n 2.120 1.50 +-0.27 -30" + "\n 3.384 2.23 0.0864 -40" + "\n 4.538 2.93 0.0274 -50" + "\n 5.658 3.62 0.00868 -60" + "\n 6.764 4.32 0.00275 -70" + "\n 7.865 5.0 0.000868 -80" + "\n 8.960 5.7 0.000275 -90" + "\n 10.056 6.4 0.000087 -100" + "\n" + "\n Above, ripples are in dB, and the transition band width is " + "\n approximately D*Fs/N, where Fs = sampling rate, " + "\n and N = window length. PB = 'pass band' and SB = 'stop band'." + "\n Alternatively, D is the transition widths in bins given a" + "\n length N DFT (i.e. a window transform with no zero padding." + "\n"; + + +int main(void) +{ + HWORD Imp[MAXNWING]; /* Filter coefficients */ + HWORD ImpD[MAXNWING]; /* ImpD[i] = ImpD[i+1] - ImpD[i] */ + double Froll, Beta; + UHWORD Nmult, Nwing, LpScl; + int err; + + Froll = 0.90; + Beta = 9; + Nmult = 65; + while (1) + { + Froll = GetDouble("Normalized Roll-off freq (0<Froll<=1)", + Froll, FrollHelp); + Beta = GetDouble("Beta", Beta, BetaHelp); + Nmult = GetUHWORD("Odd filter length 'Nmult'", Nmult, NmultHelp); + if ((Nmult&1) == 0) { + Nmult++; + printf("Filter length increased to %d to make it odd.\n",Nmult); + } + Nwing = Npc*(Nmult-1)/2; /* # of filter coeffs in right wing */ + printf("\n"); + if (!(Nmult % 2)) + printf("Error: Nmult must be odd and greater than zero\n"); + else if ((err = makeFilter(Imp, ImpD, &LpScl, Nwing, Froll, Beta))) { + printf("*** Error: Unable to make filter.\n"); + if (err == 1) + printf("\tNmult=%d too large for MAXNWING=%d\n",Nmult,MAXNWING); + else if (err == 2) + printf("\tNormalized roll-off freq Froll must be between 0 and 1\n"); + else if (err == 3) + printf("\tHeisenberg says Beta must be greater or equal to 1\n"); + else if (err == 4) { + printf("\tUnity-gain scale factor overflows 16-bit half-word\n"); + printf("\tFilter design was probably way off. Try relaxing specs.\n"); + } + } else if ((err = writeFilter(Imp, ImpD, LpScl, Nmult, Nwing))) + printf("Error: Unable to write filter, err=%d\n", err); + else + break; + } + return(0); +} |