FreeCalypso > hg > freecalypso-reveng
comparison 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 |
comparison
equal
deleted
inserted
replaced
375:6057c98d11a9 | 376:9b3e5be96bab |
---|---|
1 /* | |
2 * This program computes the frequency response of a Calypso DSP FIR filter | |
3 * whose coefficients have been captured somewhere out in the wild. | |
4 * The math has been taken from section 2.2.2 of this article: | |
5 * | |
6 * https://dspguru.com/dsp/faqs/fir/properties/ | |
7 */ | |
8 | |
9 #include <math.h> | |
10 #include <stdio.h> | |
11 #include <stdlib.h> | |
12 | |
13 #define NCOEFF 31 | |
14 | |
15 int coeff_int[NCOEFF]; | |
16 float coeff_float[NCOEFF]; | |
17 unsigned nsteps; | |
18 float freq_step, omega_step; | |
19 float freq, omega; | |
20 | |
21 static void | |
22 coeff_to_float() | |
23 { | |
24 unsigned n; | |
25 | |
26 for (n = 0; n < NCOEFF; n++) | |
27 coeff_float[n] = coeff_int[n] / 16384.0f; | |
28 } | |
29 | |
30 static void | |
31 do_one_freq() | |
32 { | |
33 unsigned n; | |
34 float angle_arg, rsum, isum; | |
35 float gain, db; | |
36 | |
37 angle_arg = 0; | |
38 rsum = 0; | |
39 isum = 0; | |
40 for (n = 0; n < NCOEFF; n++) { | |
41 rsum += coeff_float[n] * cosf(angle_arg); | |
42 isum -= coeff_float[n] * sinf(angle_arg); | |
43 angle_arg += omega; | |
44 } | |
45 gain = hypotf(rsum, isum); | |
46 db = log10f(gain) * 20.0f; | |
47 printf("%.2f\t%f\t%.2f\n", freq, gain, db); | |
48 } | |
49 | |
50 main(argc, argv) | |
51 char **argv; | |
52 { | |
53 unsigned n; | |
54 | |
55 if (argc != 3) { | |
56 fprintf(stderr, "usage: %s coeff-file nsteps\n", argv[0]); | |
57 exit(1); | |
58 } | |
59 if (read_fir_coeff_table_int(argv[1], coeff_int) < 0) | |
60 exit(1); /* error msg already printed */ | |
61 coeff_to_float(); | |
62 nsteps = strtoul(argv[2], 0, 0); | |
63 if (nsteps < 1) { | |
64 fprintf(stderr, "error: nsteps argument must be >= 1\n"); | |
65 exit(1); | |
66 } | |
67 freq_step = 4000.0f / nsteps; | |
68 omega_step = M_PI / nsteps; | |
69 n = 0; | |
70 freq = 0; | |
71 omega = 0; | |
72 for (;;) { | |
73 do_one_freq(); | |
74 if (n >= nsteps) | |
75 break; | |
76 n++; | |
77 freq += freq_step; | |
78 omega += omega_step; | |
79 } | |
80 exit(0); | |
81 } |