double * lsx_design_lpf( double Fp, /* End of pass-band */ double Fs, /* Start of stop-band */ double Fn, /* Nyquist freq; e.g. 0.5, 1, PI */ double att, /* Stop-band attenuation in dB */ int * num_taps, /* 0: value will be estimated */ int k, /* >0: number of phases; <0: num_taps �ß 1 (mod -k) */ double beta) /* <0: value will be estimated */ { int n = *num_taps, phases = max(k, 1), modulo = max(-k, 1); double tr_bw, Fc, rho = phases == 1? .5 : att < 120? .63 : .75; Fp /= fabs(Fn), Fs /= fabs(Fn); /* Normalise to Fn = 1 */ tr_bw = .5 * (Fs - Fp); /* Transition band-width: 6dB to stop points */ tr_bw /= phases, Fs /= phases; tr_bw = min(tr_bw, .5 * Fs); Fc = Fs - tr_bw; assert(Fc - tr_bw >= 0); lsx_kaiser_params(att, Fc, tr_bw, &beta, num_taps); if (!n) *num_taps = phases > 1 ? *num_taps / phases * phases + phases - 1 : (*num_taps + modulo - 2) / modulo * modulo + 1; return Fn < 0? 0 : lsx_make_lpf( *num_taps, Fc, beta, rho, (double)phases, sox_false); }
static double * lpf(double Fn, double Fc, double tbw, int * num_taps, double att, double * beta, sox_bool round) { if ((Fc /= Fn) <= 0 || Fc >= 1) { *num_taps = 0; return NULL; } att = att? att : 120; *beta = *beta < 0? lsx_kaiser_beta(att) : *beta; if (!*num_taps) { int n = lsx_lpf_num_taps(att, (tbw? tbw / Fn : .05) * .5, 0); *num_taps = range_limit(n, 11, 32767); if (round) *num_taps = 1 + 2 * (int)((int)((*num_taps / 2) * Fc + .5) / Fc + .5); lsx_report("num taps = %i (from %i)", *num_taps, n); } return lsx_make_lpf(*num_taps |= 1, Fc, *beta, 1., sox_false); }