libdspl-2.0
Библиотека алгоритмов цифровой обработки сигналов
Расчет КИХ-фильтров

Функции расчета цифровых КИХ-фильтров. Подробнее...

Функции

int fir_linphase (int ord, double w0, double w1, int filter_type, int win_type, double win_param, double *h)
 Расчет коэффициентов линейно-фазового КИХ-фильтра методом оконного взвешивания. Подробнее...
 

Подробное описание

Функции расчета цифровых КИХ-фильтров.

Функции

◆ fir_linphase()

int fir_linphase ( int  ord,
double  w0,
double  w1,
int  filter_type,
int  win_type,
double  win_param,
double *  h 
)

Расчет коэффициентов линейно-фазового КИХ-фильтра методом оконного взвешивания.


Функция рассчитывает коэффициенты передаточной характеристики

\[ H(z) = \sum_{n = 0}^{ord} h_n z^{-n} \]

цифрового линейно-фазового КИХ-фильтра фильтра.

Аргументы
[in]ordПорядок фильтра (количество элементов задержки).
Количество коэффициентов фильтра равно ord+1.

[in]w0Нормированная частота среза ФНЧ или ФВЧ, или левая частота среза для полосового и режекторного фильтра.

[in]w1Правая частота среза полосового и режекторного фильтра.
Данный параметр игнорируется для ФНЧ и ФВЧ.
Частота w1 должна быть больше w0.

[in]filter_typeТип фильтра.
Данный параметр определяет тип фильтра и может принимать одно из значений:
DSPL_FILTER_LPF   - фильтр нижних частот;
DSPL_FILTER_HPF   - фильтр верхних частот;
DSPL_FILTER_BPASS - полосовой фильтр;
DSPL_FILTER_BSTOP - режекторный фильтр.


[in]win_typeТип оконной функции.
Может принимать одно из следующих значений:
-------------------------------------------------------------------------
Значение  win_type           |  Описание
-----------------------------|-------------------------------------------
 DSPL_WIN_BARTLETT           | Непараметрическое окно Бартлетта
-----------------------------|-------------------------------------------
 DSPL_WIN_BARTLETT_HANN      | Непараметрическое окно Бартлетта-Ханна
-----------------------------|-------------------------------------------
 DSPL_WIN_BLACKMAN           | Непараметрическое окно Блэкмана 
-----------------------------|-------------------------------------------
 DSPL_WIN_BLACKMAN_HARRIS    | Непараметрическое окно Блэкмана-Харриса
-----------------------------|-------------------------------------------
 DSPL_WIN_BLACKMAN_NUTTALL   | Непараметрическое окно Блэкмана-Натталла
-----------------------------|-------------------------------------------
 DSPL_WIN_CHEBY              | Параметрическое окно Дольф-Чебышева.
                             | Параметр  win_param  задает уровень
                             | боковых лепестков в дБ.
-----------------------------|-------------------------------------------
 DSPL_WIN_COS                | Непараметрическое косинус-окно
-----------------------------|-------------------------------------------
 DSPL_WIN_FLAT_TOP           | Непараметрическое окно с максимально 
                             | плоской вершиной
-----------------------------|-------------------------------------------
 DSPL_WIN_GAUSSIAN           | Параметрическое окно Гаусса
-----------------------------|-------------------------------------------
 DSPL_WIN_HAMMING            | Непараметрическое окно Хемминга
-----------------------------|-------------------------------------------
 DSPL_WIN_HANN               | Непараметрическое окно Ханна
-----------------------------|-------------------------------------------
 DSPL_WIN_KAISER             | Параметрическое окно Кайзера
-----------------------------|-------------------------------------------
 DSPL_WIN_LANCZOS            | Непараметрическое окно Ланкзоса
-----------------------------|-------------------------------------------
 DSPL_WIN_NUTTALL            | Непараметрическое окно Натталла
-----------------------------|-------------------------------------------
 DSPL_WIN_RECT               | Непараметрическое прямоугольное окно
-------------------------------------------------------------------------


[in]win_paramПараметр окна.
Данный параметр применяется только для параметрических оконных функций.
Для непараметрических окон игнорируется.

[out]hУказатель на вектор коэффициентов линейно-фазового КИХ-фильтра \(H(z)\).
Размер вектора [ord+1 x 1].
Память должна быть выделена.

Заметки
Для соблюдения условия линейной ФЧХ используются только симметричные окна.

Расчет режекторного линейно-фазового КИХ-фильтра (если filter_type = DSPL_FILTER_BSTOP) производится только для фильтров чётного порядка ord. В случае нечетного порядка ord функция вернет код ошибки ERROR_FILTER_ORD.
Возвращает
RES_OK Фильтр рассчитан успешно.
В противном случае код ошибки.

Пример использования функции:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
/*filter order */
#define ORD 64
#define W0 0.3
#define W1 0.7
/* 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, 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, NULL, ord, w, n, DSPL_FLAG_LOGMAG, mag, NULL, NULL);
/* Frequency normaliztion from 0 to 1 */
for(k = 0; k < N; k++)
w[k] /= M_PI;
/* 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 */
/* FIR filter coeff. vectors */
double h[ORD+1];
/*------------------------------------------------------------------------*/
fir_linphase(ORD, W0, W1, DSPL_FILTER_LPF, DSPL_WIN_RECT, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_lpf_rect.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_LPF, DSPL_WIN_HAMMING, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_lpf_hamming.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_LPF, DSPL_WIN_BLACKMAN, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_lpf_blackman.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_LPF, DSPL_WIN_BLACKMAN_HARRIS, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_lpf_blackman_harris.txt");
/*------------------------------------------------------------------------*/
fir_linphase(ORD, W0, W1, DSPL_FILTER_HPF, DSPL_WIN_RECT, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_hpf_rect.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_HPF, DSPL_WIN_HAMMING, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_hpf_hamming.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_HPF, DSPL_WIN_BLACKMAN, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_hpf_blackman.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_HPF, DSPL_WIN_BLACKMAN_HARRIS, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_hpf_blackman_harris.txt");
/*------------------------------------------------------------------------*/
fir_linphase(ORD, W0, W1, DSPL_FILTER_BPASS, DSPL_WIN_RECT, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_bpass_rect.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_BPASS, DSPL_WIN_HAMMING, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_bpass_hamming.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_BPASS, DSPL_WIN_BLACKMAN, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_bpass_blackman.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_BPASS, DSPL_WIN_BLACKMAN_HARRIS, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_bpass_blackman_harris.txt");
/*------------------------------------------------------------------------*/
fir_linphase(ORD, W0, W1, DSPL_FILTER_BSTOP, DSPL_WIN_RECT, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_bstop_rect.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_BSTOP, DSPL_WIN_HAMMING, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_bstop_hamming.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_BSTOP, DSPL_WIN_BLACKMAN, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_bstop_blackman.txt");
fir_linphase(ORD, W0, W1, DSPL_FILTER_BSTOP, DSPL_WIN_BLACKMAN_HARRIS, 0, h);
freq_resp_write2txt(h, ORD, N, "dat/fir_bstop_blackman_harris.txt");
/*------------------------------------------------------------------------*/
/* plotting by GNUPLOT */
gnuplot_create(argc, argv, 920, 840, "img/fir_linphase_test.png", &hplot);
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set grid");
gnuplot_cmd(hplot, "unset xlabel");
gnuplot_cmd(hplot, "set yrange [-130: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, "set ylabel 'Magnitude, dB'");
gnuplot_cmd(hplot, "set title 'Rect win'");
gnuplot_cmd(hplot, "plot 'dat/fir_lpf_rect.txt' with lines");
gnuplot_cmd(hplot, "unset ylabel");
gnuplot_cmd(hplot, "set title 'Hamming win'");
gnuplot_cmd(hplot, "plot 'dat/fir_lpf_hamming.txt' with lines");
gnuplot_cmd(hplot, "set title 'Blackman win'");
gnuplot_cmd(hplot, "plot 'dat/fir_lpf_blackman.txt' with lines");
gnuplot_cmd(hplot, "set title 'Blackman-Harris win'");
gnuplot_cmd(hplot, "plot 'dat/fir_lpf_blackman_harris.txt' with lines");
gnuplot_cmd(hplot, "unset title");
gnuplot_cmd(hplot, "set ylabel 'Magnitude, dB'");
gnuplot_cmd(hplot, "plot 'dat/fir_hpf_rect.txt' with lines");
gnuplot_cmd(hplot, "unset ylabel");
gnuplot_cmd(hplot, "plot 'dat/fir_hpf_hamming.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fir_hpf_blackman.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fir_hpf_blackman_harris.txt' with lines");
gnuplot_cmd(hplot, "set ylabel 'Magnitude, dB'");
gnuplot_cmd(hplot, "plot 'dat/fir_bpass_rect.txt' with lines");
gnuplot_cmd(hplot, "unset ylabel");
gnuplot_cmd(hplot, "plot 'dat/fir_bpass_hamming.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fir_bpass_blackman.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fir_bpass_blackman_harris.txt' with lines");
gnuplot_cmd(hplot, "set ylabel 'Magnitude, dB'");
gnuplot_cmd(hplot, "set xlabel 'normalized frequency'");
gnuplot_cmd(hplot, "plot 'dat/fir_bstop_rect.txt' with lines");
gnuplot_cmd(hplot, "unset ylabel");
gnuplot_cmd(hplot, "plot 'dat/fir_bstop_hamming.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fir_bstop_blackman.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fir_bstop_blackman_harris.txt' with lines");
gnuplot_cmd(hplot, "unset multiplot");
gnuplot_close(hplot);
/* free dspl handle */
dspl_free(hdspl);
return 0;
}

Программа расчитывает коэффициенты и АЧХ линейно-фазовых КИХ-фильтров нижних, верхних частот, полосовых и режекторных с применением различных весовых окон: прямоугольное, Хемминга, Блэкмана и Блэкмана-Харриса.
Полученные АЧХ выводятся на график

Автор
Бахурин Сергей www.dsplib.org

См. определение в файле fir_linphase.c строка 321

void gnuplot_close(void *h)
Закрыть хэндл GNUPLOT.
Definition: gnuplot_close.c:80
void * dspl_load()
Произвести динамическую линковку и загрузить функции libdspl-2.0.
void gnuplot_cmd(void *h, char *cmd)
Функция посылает команду cmd пакету GNUPLOT, для построения или оформления графика,...
Definition: gnuplot_cmd.c:82
int fir_linphase(int ord, double w0, double w1, int filter_type, int win_type, double win_param, double *h)
Расчет коэффициентов линейно-фазового КИХ-фильтра методом оконного взвешивания.
Definition: fir_linphase.c:321
int writetxt(double *x, double *y, int n, char *fn)
Сохранить вещественные данные в текстовый файл
Definition: writetxt.c:122
int filter_freq_resp(double *b, double *a, int ord, double *w, int n, int flag, double *mag, double *phi, double *tau)
Расчет амплитудно-частотной (АЧХ), фазочастотной характеристик (ФЧХ), а также группового времени запа...
void dspl_free(void *handle)
Очищает связанную ранее динамическую библиотеку DSPL-2.0.
int linspace(double x0, double x1, int n, int type, double *x)
Функция заполняет массив линейно-нарастающими, равноотстоящими значениями от x0 до x1
Definition: linspace.c:169
int gnuplot_create(int argc, char *argv[], int w, int h, char *fn_png, void **hplot)
Создать график GNUPLOT.