kopia lustrzana https://github.com/Dsplib/libdspl-2.0
197 wiersze
6.5 KiB
C
197 wiersze
6.5 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "dspl.h"
|
|
|
|
/* Low-pass filter order */
|
|
#define LPF_ORD 6
|
|
|
|
/* High-pass filter order */
|
|
#define HPF_ORD 6
|
|
|
|
/* band-pass filter order */
|
|
#define BPF_ORD 12
|
|
|
|
/* Band-stop filter order */
|
|
#define BSF_ORD 12
|
|
|
|
/* Maximum filter order */
|
|
#define MAX_ORD BPF_ORD
|
|
|
|
/* Stopband suppression (dB) */
|
|
#define RS 60.0
|
|
|
|
/* Pass-band maximum distortion (dB) */
|
|
#define RP 2.0
|
|
|
|
/* Frequency response vector size */
|
|
#define N 1024
|
|
|
|
|
|
/*
|
|
function calculates filter frequency response and save magnitude to
|
|
the text file.
|
|
params: b - pointer to the transfer fuction H(z) numerator vector
|
|
a - pointer to the transfer fuction H(z) denominator vector
|
|
ord - filter order
|
|
n - number of magnitude vector size
|
|
fn - file name
|
|
*/
|
|
void freq_resp_write2txt(double* b, double* a, int ord, int n, char* fn)
|
|
{
|
|
double *w = NULL, *mag = NULL;
|
|
int k;
|
|
|
|
w = (double*)malloc(n*sizeof(double));
|
|
mag = (double*)malloc(n*sizeof(double));
|
|
|
|
/* Normalized frequency from 0 to pi */
|
|
linspace(0, M_PI, n , DSPL_PERIODIC, w);
|
|
|
|
/* Magnitude (dB) calculation */
|
|
filter_freq_resp(b, a, ord, w, n, DSPL_FLAG_LOGMAG, mag, NULL, NULL);
|
|
|
|
/* Frequency normalization from 0 to 1 and check magnitude */
|
|
|
|
for(k = 0; k < N; k++)
|
|
{
|
|
w[k] /= M_PI;
|
|
|
|
/* Set magnitude to -400 dB if it is inf. */
|
|
if(isinf(mag[k]))
|
|
mag[k] = -400.0;
|
|
}
|
|
|
|
|
|
/* Save magnitude to the txt file */
|
|
writetxt(w, mag, n, fn);
|
|
|
|
free(w);
|
|
free(mag);
|
|
}
|
|
|
|
|
|
/*
|
|
* Main program
|
|
*/
|
|
int main(int argc, char* argv[])
|
|
{
|
|
void* hdspl; /* DSPL handle */
|
|
void* hplot; /* GNUPLOT handle */
|
|
hdspl = dspl_load(); /* Load DSPL functions */
|
|
|
|
/* Transfer function H(z) coeff. vectors */
|
|
double a[MAX_ORD+1], b[MAX_ORD+1];
|
|
|
|
/* Batterworth */
|
|
|
|
/* LPF Batterworth */
|
|
iir(RP, RS, LPF_ORD, 0.3, 0.0, DSPL_FILTER_BUTTER | DSPL_FILTER_LPF, b, a);
|
|
freq_resp_write2txt(b, a, LPF_ORD, N, "dat/iir_butter_lpf.txt");
|
|
|
|
/* HPF Batterworth */
|
|
iir(RP, RS, HPF_ORD, 0.3, 0.0, DSPL_FILTER_BUTTER | DSPL_FILTER_HPF, b, a);
|
|
freq_resp_write2txt(b, a, HPF_ORD, N, "dat/iir_butter_hpf.txt");
|
|
|
|
/* Band-pass Batterworth */
|
|
iir(RP, RS, BPF_ORD, 0.3, 0.7, DSPL_FILTER_BUTTER | DSPL_FILTER_BPASS, b, a);
|
|
freq_resp_write2txt(b, a, BPF_ORD, N, "dat/iir_butter_bpf.txt");
|
|
|
|
/* Band-stop Batterworth */
|
|
iir(RP, RS, BSF_ORD, 0.3, 0.7, DSPL_FILTER_BUTTER | DSPL_FILTER_BSTOP, b, a);
|
|
freq_resp_write2txt(b, a, BSF_ORD, N, "dat/iir_butter_bsf.txt");
|
|
|
|
/* Chebyshev type 1 */
|
|
|
|
/* LPF Chebyshev type 1 */
|
|
iir(RP, RS, LPF_ORD, 0.3, 0.0, DSPL_FILTER_CHEBY1 | DSPL_FILTER_LPF, b, a);
|
|
freq_resp_write2txt(b, a, LPF_ORD, N, "dat/iir_cheby1_lpf.txt");
|
|
|
|
/* HPF Chebyshev type 1 */
|
|
iir(RP, RS, HPF_ORD, 0.3, 0.0, DSPL_FILTER_CHEBY1 | DSPL_FILTER_HPF, b, a);
|
|
freq_resp_write2txt(b, a, HPF_ORD, N, "dat/iir_cheby1_hpf.txt");
|
|
|
|
/* Bnad-pass Chebyshev type 1 */
|
|
iir(RP, RS, BPF_ORD, 0.3, 0.7, DSPL_FILTER_CHEBY1 | DSPL_FILTER_BPASS, b, a);
|
|
freq_resp_write2txt(b, a, BPF_ORD, N, "dat/iir_cheby1_bpf.txt");
|
|
|
|
/* Bnad-stop Chebyshev type 1 */
|
|
iir(RP, RS, BSF_ORD, 0.3, 0.7, DSPL_FILTER_CHEBY1 | DSPL_FILTER_BSTOP, b, a);
|
|
freq_resp_write2txt(b, a, BSF_ORD, N, "dat/iir_cheby1_bsf.txt");
|
|
|
|
/* Chebyshev type 2 */
|
|
|
|
/* LPF Chebyshev type 2 */
|
|
iir(RP, RS, LPF_ORD, 0.3, 0.0, DSPL_FILTER_CHEBY2 | DSPL_FILTER_LPF, b, a);
|
|
freq_resp_write2txt(b, a, LPF_ORD, N, "dat/iir_cheby2_lpf.txt");
|
|
|
|
/* HPF Chebyshev type 2 */
|
|
iir(RP, RS, HPF_ORD, 0.3, 0.0, DSPL_FILTER_CHEBY2 | DSPL_FILTER_HPF, b, a);
|
|
freq_resp_write2txt(b, a, HPF_ORD, N, "dat/iir_cheby2_hpf.txt");
|
|
|
|
/* Band-pass Chebyshev type 2 */
|
|
iir(RP, RS, BPF_ORD, 0.3, 0.7, DSPL_FILTER_CHEBY2 | DSPL_FILTER_BPASS, b, a);
|
|
freq_resp_write2txt(b, a, BPF_ORD, N, "dat/iir_cheby2_bpf.txt");
|
|
|
|
/* Band-stop Chebyshev type 2 */
|
|
iir(RP, RS, BSF_ORD, 0.3, 0.7, DSPL_FILTER_CHEBY2 | DSPL_FILTER_BSTOP, b, a);
|
|
freq_resp_write2txt(b, a, BSF_ORD, N, "dat/iir_cheby2_bsf.txt");
|
|
|
|
/* Elliptic */
|
|
|
|
/* LPF Elliptic */
|
|
iir(RP, RS, LPF_ORD, 0.3, 0.0, DSPL_FILTER_ELLIP | DSPL_FILTER_LPF, b, a);
|
|
freq_resp_write2txt(b, a, LPF_ORD, N, "dat/iir_ellip_lpf.txt");
|
|
|
|
/* HPF Elliptic */
|
|
iir(RP, RS, HPF_ORD, 0.3, 0.0, DSPL_FILTER_ELLIP | DSPL_FILTER_HPF, b, a);
|
|
freq_resp_write2txt(b, a, HPF_ORD, N, "dat/iir_ellip_hpf.txt");
|
|
|
|
/* Band-pass Elliptic */
|
|
iir(RP, RS, BPF_ORD, 0.3, 0.7, DSPL_FILTER_ELLIP | DSPL_FILTER_BPASS, b, a);
|
|
freq_resp_write2txt(b, a, BPF_ORD, N, "dat/iir_ellip_bpf.txt");
|
|
|
|
/* Band-stop Elliptic */
|
|
iir(RP, RS, BSF_ORD, 0.3, 0.7, DSPL_FILTER_ELLIP | DSPL_FILTER_BSTOP, b, a);
|
|
freq_resp_write2txt(b, a, BSF_ORD, N, "dat/iir_ellip_bsf.txt");
|
|
|
|
/* plotting by GNUPLOT */
|
|
gnuplot_create(argc, argv, 920, 840, "img/iir_test.png", &hplot);
|
|
gnuplot_cmd(hplot, "unset key");
|
|
gnuplot_cmd(hplot, "set grid");
|
|
gnuplot_cmd(hplot, "set xlabel 'normalized frequency'");
|
|
gnuplot_cmd(hplot, "set ylabel 'Magnitude, dB'");
|
|
gnuplot_cmd(hplot, "set yrange [-100:5]");
|
|
gnuplot_cmd(hplot, "set xtics 0,1");
|
|
gnuplot_cmd(hplot, "set xtics add ('0.3' 0.3)");
|
|
gnuplot_cmd(hplot, "set xtics add ('0.7' 0.7)");
|
|
gnuplot_cmd(hplot, "set xtics add ('1' 1)");
|
|
gnuplot_cmd(hplot, "set multiplot layout 4,4 rowsfirst");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_butter_lpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_butter_hpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_butter_bpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_butter_bsf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_cheby1_lpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_cheby1_hpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_cheby1_bpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_cheby1_bsf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_cheby2_lpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_cheby2_hpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_cheby2_bpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_cheby2_bsf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_ellip_lpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_ellip_hpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_ellip_bpf.txt' with lines");
|
|
gnuplot_cmd(hplot, "plot 'dat/iir_ellip_bsf.txt' with lines");
|
|
gnuplot_cmd(hplot, "unset multiplot");
|
|
gnuplot_close(hplot);
|
|
|
|
/* free dspl handle */
|
|
dspl_free(hdspl);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|