FreeCalypso > hg > freecalypso-reveng
diff fir/freqresp.c @ 376:9b3e5be96bab
fir2freq: a tool for analyzing captured FIR coefficient sets
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 02 Aug 2021 04:59:46 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fir/freqresp.c Mon Aug 02 04:59:46 2021 +0000 @@ -0,0 +1,81 @@ +/* + * This program computes the frequency response of a Calypso DSP FIR filter + * whose coefficients have been captured somewhere out in the wild. + * The math has been taken from section 2.2.2 of this article: + * + * https://dspguru.com/dsp/faqs/fir/properties/ + */ + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> + +#define NCOEFF 31 + +int coeff_int[NCOEFF]; +float coeff_float[NCOEFF]; +unsigned nsteps; +float freq_step, omega_step; +float freq, omega; + +static void +coeff_to_float() +{ + unsigned n; + + for (n = 0; n < NCOEFF; n++) + coeff_float[n] = coeff_int[n] / 16384.0f; +} + +static void +do_one_freq() +{ + unsigned n; + float angle_arg, rsum, isum; + float gain, db; + + angle_arg = 0; + rsum = 0; + isum = 0; + for (n = 0; n < NCOEFF; n++) { + rsum += coeff_float[n] * cosf(angle_arg); + isum -= coeff_float[n] * sinf(angle_arg); + angle_arg += omega; + } + gain = hypotf(rsum, isum); + db = log10f(gain) * 20.0f; + printf("%.2f\t%f\t%.2f\n", freq, gain, db); +} + +main(argc, argv) + char **argv; +{ + unsigned n; + + if (argc != 3) { + fprintf(stderr, "usage: %s coeff-file nsteps\n", argv[0]); + exit(1); + } + if (read_fir_coeff_table_int(argv[1], coeff_int) < 0) + exit(1); /* error msg already printed */ + coeff_to_float(); + nsteps = strtoul(argv[2], 0, 0); + if (nsteps < 1) { + fprintf(stderr, "error: nsteps argument must be >= 1\n"); + exit(1); + } + freq_step = 4000.0f / nsteps; + omega_step = M_PI / nsteps; + n = 0; + freq = 0; + omega = 0; + for (;;) { + do_one_freq(); + if (n >= nsteps) + break; + n++; + freq += freq_step; + omega += omega_step; + } + exit(0); +}