kopia lustrzana https://github.com/Dsplib/libdspl-2.0
iir function is using normlization:
a[m] = a[m] / a[0], m = 1... ord b[m] = b[m] / a[0], m = 1... ord a[0] = 1.0 added doc for individual functions group_delay and phase_delay filter_iir is also using normlization a[m] = a[m] / a[0], m = 1... ord b[m] = b[m] / a[0], m = 1... ord a[0] = 1.0 Changes to be committed: modified: dspl/src/conv.c modified: dspl/src/filter_an.c modified: dspl/src/filter_iir.cpull/6/merge
rodzic
ea9bbcfee9
commit
52a33913b3
|
@ -993,15 +993,16 @@ dat/sf.txt - сигнал на выходе фильтра.
|
||||||
int DSPL_API filter_iir(double* b, double* a, int ord,
|
int DSPL_API filter_iir(double* b, double* a, int ord,
|
||||||
double* x, int n, double* y)
|
double* x, int n, double* y)
|
||||||
{
|
{
|
||||||
double* buf = NULL;
|
double *buf = NULL;
|
||||||
double* an = NULL;
|
double *an = NULL;
|
||||||
|
double *bn = NULL;
|
||||||
double u;
|
double u;
|
||||||
int k;
|
int k;
|
||||||
int m;
|
int m;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
if(!b || !x || !y)
|
if(!b || !x || !y)
|
||||||
return ERROR_PTR;
|
return ERROR_PTR;
|
||||||
|
|
||||||
if(ord < 1 || n < 1)
|
if(ord < 1 || n < 1)
|
||||||
return ERROR_SIZE;
|
return ERROR_SIZE;
|
||||||
|
@ -1016,10 +1017,19 @@ int DSPL_API filter_iir(double* b, double* a, int ord,
|
||||||
memset(buf, 0, count*sizeof(double));
|
memset(buf, 0, count*sizeof(double));
|
||||||
|
|
||||||
if(!a)
|
if(!a)
|
||||||
|
{
|
||||||
memset(an, 0, count*sizeof(double));
|
memset(an, 0, count*sizeof(double));
|
||||||
|
bn = b;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
bn = (double*) malloc(count*sizeof(double));
|
||||||
for(k = 0; k < count; k++)
|
for(k = 0; k < count; k++)
|
||||||
|
{
|
||||||
an[k] = a[k] / a[0];
|
an[k] = a[k] / a[0];
|
||||||
|
bn[k] = b[k] / a[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(k = 0; k < n; k++)
|
for(k = 0; k < n; k++)
|
||||||
{
|
{
|
||||||
|
@ -1032,13 +1042,15 @@ int DSPL_API filter_iir(double* b, double* a, int ord,
|
||||||
buf[0] = x[k] - u;
|
buf[0] = x[k] - u;
|
||||||
y[k] = 0.0;
|
y[k] = 0.0;
|
||||||
for(m = 0; m < count; m++)
|
for(m = 0; m < count; m++)
|
||||||
y[k] += buf[m] * b[m];
|
y[k] += buf[m] * bn[m];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buf)
|
if(buf)
|
||||||
free(buf);
|
free(buf);
|
||||||
if(an)
|
if(an)
|
||||||
free(an);
|
free(an);
|
||||||
|
if(bn && (bn != b))
|
||||||
|
free(bn);
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#ifdef DOXYGEN_ENGLISH
|
#ifdef DOXYGEN_ENGLISH
|
||||||
/*! ****************************************************************************
|
/*! ****************************************************************************
|
||||||
\ingroup FILTER_ANALYSIS_GROUP
|
\ingroup FILTER_ANALYSIS_GROUP
|
||||||
int DSPL_API group_delay(double* b, double* a, int ord, int flag,
|
\fn int DSPL_API group_delay(double* b, double* a, int ord, int flag,
|
||||||
double* w, int n, double* tau)
|
double* w, int n, double* tau)
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
|
@ -40,7 +40,7 @@ Group delay calculation for digital or analog filter corresponds to
|
||||||
|
|
||||||
Group delay is describes as:
|
Group delay is describes as:
|
||||||
\f[
|
\f[
|
||||||
\tau_g(\omega) = - \dfrac{d\Phi(\omega)}{d\omega},
|
\tau_g(\omega) = - \frac{d\Phi(\omega)}{d\omega},
|
||||||
\f]
|
\f]
|
||||||
here \f$\Phi(\omega)\f$ -- filter phase response, \f$\omega\f$ is angular
|
here \f$\Phi(\omega)\f$ -- filter phase response, \f$\omega\f$ is angular
|
||||||
frequency for analog filter, or normalized frequency for digital filter.
|
frequency for analog filter, or normalized frequency for digital filter.
|
||||||
|
@ -98,14 +98,14 @@ Else \ref ERROR_CODE_GROUP "code error".
|
||||||
#ifdef DOXYGEN_RUSSIAN
|
#ifdef DOXYGEN_RUSSIAN
|
||||||
/*! ****************************************************************************
|
/*! ****************************************************************************
|
||||||
\ingroup FILTER_ANALYSIS_GROUP
|
\ingroup FILTER_ANALYSIS_GROUP
|
||||||
int DSPL_API group_delay(double* b, double* a, int ord, int flag,
|
\fn int DSPL_API group_delay(double* b, double* a, int ord, int flag,
|
||||||
double* w, int n, double* tau)
|
double* w, int n, double* tau)
|
||||||
\brief
|
\brief
|
||||||
Расчет группового времени запаздывания цифрового или аналогового фильтра.
|
Расчет группового времени запаздывания цифрового или аналогового фильтра.
|
||||||
|
|
||||||
Групповое время запаздывания определяется как:
|
Групповое время запаздывания определяется как:
|
||||||
\f[
|
\f[
|
||||||
\tau_g(\omega) = - \dfrac{d\Phi(\omega)}{d\omega},
|
\tau_g(\omega) = - \frac{d\Phi(\omega)}{d\omega},
|
||||||
\f]
|
\f]
|
||||||
где \f$\Phi(\omega)\f$ -- ФЧХ фильтра, \f$\omega\f$ циктическая частот в случае
|
где \f$\Phi(\omega)\f$ -- ФЧХ фильтра, \f$\omega\f$ циктическая частот в случае
|
||||||
аналогового фильтра, или нормированная частота цифрового фильтра.
|
аналогового фильтра, или нормированная частота цифрового фильтра.
|
||||||
|
@ -157,7 +157,7 @@ DSPL_FLAG_DIGITAL Коэффициенты относятся к цифрово
|
||||||
Память должна быть выделена. \n
|
Память должна быть выделена. \n
|
||||||
|
|
||||||
\return
|
\return
|
||||||
`RES_OK` Параметры фильтра рассчитаны успешно. \n
|
`RES_OK` групповая задержка фильтра рассчитана успешно. \n
|
||||||
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
|
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
|
||||||
|
|
||||||
\author Бахурин Сергей www.dsplib.org
|
\author Бахурин Сергей www.dsplib.org
|
||||||
|
@ -1053,10 +1053,139 @@ exit_label:
|
||||||
|
|
||||||
|
|
||||||
#ifdef DOXYGEN_ENGLISH
|
#ifdef DOXYGEN_ENGLISH
|
||||||
|
/*! ****************************************************************************
|
||||||
|
\ingroup FILTER_ANALYSIS_GROUP
|
||||||
|
\fn int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
|
||||||
|
double* w, int n, double* tau)
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Phase delay calculation for digital or analog filter corresponds to
|
||||||
|
\f$H(s)\f$, or \f$H(z)\f$ transfer function.
|
||||||
|
|
||||||
|
Group delay is describes as:
|
||||||
|
\f[
|
||||||
|
\tau_\{\varphi}(\omega) = - \frac{\Phi(\omega)}{\omega},
|
||||||
|
\f]
|
||||||
|
here \f$\Phi(\omega)\f$ -- filter phase response, \f$\omega\f$ is angular
|
||||||
|
frequency for analog filter, or normalized frequency for digital filter.
|
||||||
|
|
||||||
|
\param[in] b
|
||||||
|
Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
|
||||||
|
numerator coefficients vector. \n
|
||||||
|
Vector size is `[ord+1 x 1]`. \n \n
|
||||||
|
|
||||||
|
\param[in] a
|
||||||
|
Pointer to the \f$ H(s) \f$ or \f$H(z)\f$ transfer function
|
||||||
|
denominator coefficients vector. \n
|
||||||
|
Vector size is `[ord+1 x 1]`. \n \n
|
||||||
|
|
||||||
|
\param[in] ord
|
||||||
|
Filter order. \n
|
||||||
|
Transfer function \f$ H(s) \f$ or \f$H(z)\f$ numerator
|
||||||
|
and denominator coefficients number equals `ord+1`. \n \n
|
||||||
|
|
||||||
|
\param[in] flag
|
||||||
|
Binary flags to set calculation rules: \n
|
||||||
|
\verbatim
|
||||||
|
DSPL_FLAG_ANALOG Coefficients corresponds to analog filter
|
||||||
|
DSPL_FLAG_DIGITAL Coefficients corresponds to digital filter
|
||||||
|
\endverbatim
|
||||||
|
\n \n
|
||||||
|
|
||||||
|
\param[in] w
|
||||||
|
Pointer to the angular frequency \f$ \omega \f$ (rad/s),
|
||||||
|
which used for analog filter characteristics calculation
|
||||||
|
(flag sets as `DSPL_FLAG_ANALOG`). \n
|
||||||
|
For digital filter (flag sets as `DSPL_FLAG_DIGITAL`),
|
||||||
|
parameter `w` describes normalized frequency of
|
||||||
|
frequency response \f$ H \left(\mathrm{e}^{j\omega} \right) \f$.
|
||||||
|
Digital filter frequency response is \f$ 2\pi \f$-periodic function,
|
||||||
|
and vector `w` advisable to set from 0 to \f$ \pi \f$,
|
||||||
|
or from 0 to \f$ 2\pi \f$, or from \f$ -\pi \f$ to \f$ \pi \f$.
|
||||||
|
Vector size is `[n x 1]`. \n \n
|
||||||
|
|
||||||
|
\param[in] n
|
||||||
|
Size of frequency vector `w`. \n \n
|
||||||
|
|
||||||
|
\param[out] tau
|
||||||
|
Pointer to the phase delay vector. \n
|
||||||
|
Vector size is `[n x 1]`. \n
|
||||||
|
Memory must be allocated. \n \n
|
||||||
|
|
||||||
|
\return
|
||||||
|
\return `RES_OK` if function is calculated successfully. \n
|
||||||
|
Else \ref ERROR_CODE_GROUP "code error".
|
||||||
|
|
||||||
|
\author Sergey Bakhurin www.dsplib.org
|
||||||
|
***************************************************************************** */
|
||||||
#endif
|
#endif
|
||||||
#ifdef DOXYGEN_RUSSIAN
|
#ifdef DOXYGEN_RUSSIAN
|
||||||
|
/*! ****************************************************************************
|
||||||
|
\ingroup FILTER_ANALYSIS_GROUP
|
||||||
|
\fn int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
|
||||||
|
double* w, int n, double* tau)
|
||||||
|
\brief
|
||||||
|
Расчет задержки цифрового или аналогового фильтра.
|
||||||
|
|
||||||
|
Фазовая задержка определяется как:
|
||||||
|
\f[
|
||||||
|
\tau_g(\omega) = - \frac{\Phi(\omega)}{\omega},
|
||||||
|
\f]
|
||||||
|
где \f$\Phi(\omega)\f$ -- ФЧХ фильтра, \f$\omega\f$ циктическая частот в случае
|
||||||
|
аналогового фильтра, или нормированная частота цифрового фильтра.
|
||||||
|
|
||||||
|
\param[in] b
|
||||||
|
Указатель на вектор коэффициентов числителя передаточной функции
|
||||||
|
аналогового фильтра \f$ H(s) \f$ или цифрового фильтра \f$ H(z) \f$. \n
|
||||||
|
Размер вектора `[ord+1 x 1]`. \n \n
|
||||||
|
|
||||||
|
\param[in] a
|
||||||
|
Указатель на вектор коэффициентов числителя передаточной функции
|
||||||
|
аналогового фильтра \f$ H(s) \f$ или цифрового фильтра \f$ H(z) \f$. \n
|
||||||
|
Размер вектора `[ord+1 x 1]`. \n
|
||||||
|
Параметр может быть `NULL`. В этом случае расчет производится для цифрового
|
||||||
|
КИХ-фильтра с коэффициентами, заданными вектором `b`. \n\n
|
||||||
|
|
||||||
|
\param[in] ord
|
||||||
|
Порядок фильтра. Количество коэффициентов
|
||||||
|
числителя и знаменателя передаточной
|
||||||
|
функции \f$ H(s) \f$ или \f$ H(z) \f$ равно `ord+1`. \n \n
|
||||||
|
|
||||||
|
\param[in] flag
|
||||||
|
Флаг который задает тип фильтра: \n
|
||||||
|
\verbatim
|
||||||
|
DSPL_FLAG_ANALOG Коэффициенты относятся к аналоговому фильтру
|
||||||
|
DSPL_FLAG_DIGITAL Коэффициенты относятся к цифровому фильтру
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
\param[in] w
|
||||||
|
Указатель на вектор значений циклической частоты \f$ \omega \f$ (рад/с),
|
||||||
|
для которого будет рассчитаны АЧХ, ФЧХ и ГВЗ аналогового фильтра,
|
||||||
|
если установлен флаг `DSPL_FLAG_ANALOG`. \n
|
||||||
|
В случае если флаг `DSPL_FLAG_ANALOG` не установлен, то вектор частоты `w`
|
||||||
|
используется как нормированная частота комплексного коэффициента передачи
|
||||||
|
\f$ H \left(\mathrm{e}^{j\omega} \right) \f$ цифрового фильтра. \n
|
||||||
|
В этом случае характеристика цифрового фильтра является
|
||||||
|
\f$ 2\pi \f$-периодической, и вектор частоты может содержать
|
||||||
|
произвольные значения, однако целесообразно задавать
|
||||||
|
его от 0 до \f$ \pi \f$, а такжет от 0 до \f$ 2\pi \f$, или
|
||||||
|
от \f$ -\pi \f$ до \f$ \pi \f$. \n
|
||||||
|
Размер вектора `[n x 1]`. \n \n
|
||||||
|
|
||||||
|
\param[in] n
|
||||||
|
Размер вектора циклической частоты `w`. \n \n
|
||||||
|
|
||||||
|
\param[out] tau
|
||||||
|
Указатель на вектор фазовой задержки. \n
|
||||||
|
Размер вектора `[n x 1]`. \n
|
||||||
|
Память должна быть выделена. \n
|
||||||
|
|
||||||
|
\return
|
||||||
|
`RES_OK` фазовая задержка фильтра рассчитана успешно. \n
|
||||||
|
В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
|
||||||
|
|
||||||
|
\author Бахурин Сергей www.dsplib.org
|
||||||
|
***************************************************************************** */
|
||||||
#endif
|
#endif
|
||||||
int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
|
int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
|
||||||
double* w, int n, double* tau)
|
double* w, int n, double* tau)
|
||||||
|
@ -1069,13 +1198,13 @@ int DSPL_API phase_delay(double* b, double* a, int ord, int flag,
|
||||||
else
|
else
|
||||||
return ERROR_SIZE;
|
return ERROR_SIZE;
|
||||||
|
|
||||||
err = filter_freq_resp(b, a, ord, w, n,
|
err = filter_freq_resp(b, a, ord, w, n, flag | DSPL_FLAG_UNWRAP, NULL, phi, NULL);
|
||||||
flag | DSPL_FLAG_UNWRAP, NULL, phi, NULL);
|
|
||||||
if(err!=RES_OK)
|
if(err!=RES_OK)
|
||||||
goto exit_label;
|
goto exit_label;
|
||||||
for(i = 0; i < n; i++)
|
for(i = 0; i < n; i++)
|
||||||
|
{
|
||||||
tau[i] = w[i] ? ( - phi[i] / w[i]) : ( - phi[i] / (w[i] + 1E-9) );
|
tau[i] = w[i] ? ( - phi[i] / w[i]) : ( - phi[i] / (w[i] + 1E-9) );
|
||||||
|
}
|
||||||
exit_label:
|
exit_label:
|
||||||
if(phi)
|
if(phi)
|
||||||
free(phi);
|
free(phi);
|
||||||
|
|
|
@ -410,6 +410,7 @@ int DSPL_API iir(double rp, double rs, int ord, double w0, double w1,
|
||||||
double *at = NULL;
|
double *at = NULL;
|
||||||
double wa0, wa1, ws;
|
double wa0, wa1, ws;
|
||||||
int err, ord_ap = ord;
|
int err, ord_ap = ord;
|
||||||
|
int i;
|
||||||
|
|
||||||
if(((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_LPF) ||
|
if(((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_LPF) ||
|
||||||
((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_HPF))
|
((type & DSPL_FILTER_TYPE_MASK) == DSPL_FILTER_HPF))
|
||||||
|
@ -478,6 +479,14 @@ int DSPL_API iir(double rp, double rs, int ord, double w0, double w1,
|
||||||
|
|
||||||
err = bilinear(bt, at, ord, b, a);
|
err = bilinear(bt, at, ord, b, a);
|
||||||
|
|
||||||
|
for(i = 1; i <= ord; i++)
|
||||||
|
{
|
||||||
|
a[i] /= a[0];
|
||||||
|
b[i] /= a[0];
|
||||||
|
}
|
||||||
|
b[0] /= a[0];
|
||||||
|
a[0] = 1.0;
|
||||||
|
|
||||||
error_proc:
|
error_proc:
|
||||||
|
|
||||||
if(bs)
|
if(bs)
|
||||||
|
|
Ładowanie…
Reference in New Issue