added freqs_resp and unwrap. Some docs
|
@ -922,7 +922,7 @@ EXAMPLE_RECURSIVE = YES
|
|||
# that contain images that are to be included in the documentation (see the
|
||||
# \image command).
|
||||
|
||||
IMAGE_PATH =
|
||||
IMAGE_PATH = ../test/bin/img
|
||||
|
||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||
|
|
|
@ -91,12 +91,10 @@
|
|||
\return
|
||||
`RES_OK` если ДПФ рассчитана успешно. <BR>
|
||||
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Пример использования функции `dft_cmplx`:
|
||||
|
||||
\include dft_cmplx_test.c
|
||||
|
|
|
@ -70,10 +70,7 @@
|
|||
|
||||
Также необходимо заметить, что функции БПФ самостоятельно контроллируют размер,
|
||||
и самостоятельно выделяют память объекта БПФ при необходимости.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\author
|
||||
Бахурин Сергей.
|
||||
|
@ -87,6 +84,94 @@
|
|||
|
||||
|
||||
|
||||
/*! *************************************************************************************************
|
||||
\ingroup DFT_GROUP
|
||||
\fn int fft_create(fft_t *pfft, int n)
|
||||
\brief Заполнение структуры `fft_t` для алгоритма БПФ
|
||||
|
||||
Функция производит выделение памяти и рассчет векторов поворотных коэффициентов
|
||||
`n`-точечного БПФ для структуры `fft_t`.
|
||||
|
||||
|
||||
|
||||
\param[in,out] pfft Указатель на структуру `fft_t`. <BR>
|
||||
Указатель не должен быть `NULL`. <BR><BR>
|
||||
|
||||
\param[in] n Размер БПФ \f$n\f$ (должен быть равен целой степени двойки).<BR>
|
||||
|
||||
|
||||
|
||||
|
||||
\return
|
||||
`RES_OK` если структура заполнена успешно. <BR>
|
||||
В противном случае \ref ERROR_CODE_GROUP "код ошибки".<BR><BR>
|
||||
|
||||
\note
|
||||
Некоторые компиляторы при создании структуры не обнуляют ее содержимое.
|
||||
Поэтому рекомендуется произвести обнуление структуры после ее объявления:
|
||||
\code
|
||||
fft_t pfft; // объявляем объект fft_t
|
||||
int n = 64; // Размер БПФ
|
||||
|
||||
// обнуляем все поля и указатели.
|
||||
// Данные шаг рекомендуется ввиду того, что некоторые
|
||||
// компиляторы при создании переменной не инициализируют ее нулем.
|
||||
memset(&pfft, 0, sizeof(fft_t));
|
||||
|
||||
int err;
|
||||
|
||||
//создаем объект для 64-точечного БПФ
|
||||
err = fft_create(&pfft, n);
|
||||
|
||||
// .....
|
||||
|
||||
//очистить память объекта БПФ
|
||||
fft_free(&pfft);
|
||||
\endcode
|
||||
Перед выходом из программы выделенную в структуре память необходимо очистить функцией \ref fft_free .
|
||||
|
||||
|
||||
\author
|
||||
Бахурин Сергей.
|
||||
www.dsplib.org
|
||||
|
||||
|
||||
**************************************************************************************************** */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*! *************************************************************************************************
|
||||
\ingroup DFT_GROUP
|
||||
\fn void fft_free(fft_t *pfft)
|
||||
\brief Очистить структуру `fft_t` алгоритма БПФ
|
||||
|
||||
Функция производит очищение памяти промежуточных данных
|
||||
и векторов поворотных коэффициентов структуры `fft_t`.
|
||||
|
||||
|
||||
|
||||
\param[in] pfft Указатель на структуру `fft_t`. <BR>
|
||||
|
||||
\author
|
||||
Бахурин Сергей.
|
||||
www.dsplib.org
|
||||
|
||||
|
||||
**************************************************************************************************** */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*! *************************************************************************************************
|
||||
\ingroup DFT_GROUP
|
||||
\fn int fft_shift(double* x, int n, double* y)
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
Память должна быть выделена.<BR> <BR>
|
||||
|
||||
\return
|
||||
`RES_OK` Фильтр рассчитан успешно.<BR>
|
||||
`RES_OK` Комплексноый коэффициент передачи рассчитан успешно.<BR>
|
||||
В противном случае \ref ERROR_CODE_GROUP "код ошибки".<BR>
|
||||
|
||||
\author
|
||||
|
@ -49,6 +49,112 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
/*! *************************************************************************************************
|
||||
\ingroup FILTER_ANALYSIS_GROUP
|
||||
\fn int freqs_resp(double* b, double* a, int ord, double* w, int n, int flag,
|
||||
double *h, double* phi, double* tau)
|
||||
|
||||
\brief Расчет амплитудно-частотной (АЧХ), фазочастотной характеристик (ФЧХ),
|
||||
а также группового времени запаздывания (ГВЗ) аналогового фильтра.
|
||||
|
||||
Функция рассчитывает АЧХ, ФЧХ и ГВЗ аналоговго фильтра, заданного передаточной характеристикой \f$H(s)\f$
|
||||
|
||||
|
||||
\param[in] b Указатель на вектор коэффициентов числителя передаточной функции \f$H(s)\f$.<BR>
|
||||
Размер вектора `[ord+1 x 1]`.<BR><BR>
|
||||
|
||||
\param[in] a Указатель на вектор коэффициентов знаменателя передаточной функции \f$H(s)\f$.<BR>
|
||||
Размер вектора `[ord+1 x 1]`.<BR><BR>
|
||||
|
||||
\param[in] ord Порядок фильтра. Количество коэффициентов числителя и знаменателя передаточной
|
||||
функции \f$H(s)\f$ равно `ord+1`.<BR> <BR>
|
||||
|
||||
\param[in] w Указатель на вектор значений циклической частоты \f$\omega\f$ (рад/с),
|
||||
для которого будет рассчитаны АЧХ, ФЧХ и ГВЗ.<BR>
|
||||
Размер вектора `[n x 1]`.<BR><BR>
|
||||
|
||||
\param[in] n Размер вектора циклической частоты `w`.<BR> <BR>
|
||||
|
||||
|
||||
\param[in] flag Комбинация флагов, которые задают расчет параметров:<BR>
|
||||
<pre>
|
||||
DSPL_FLAG_LOG АЧХ рассчитывать в логарифмическом масштабе
|
||||
DSPL_FLAG_UNWRAP раскрывать периодичность ФЧХ`
|
||||
</pre>
|
||||
|
||||
\param[out] h Указатель на вектор АЧХ.<BR>
|
||||
Размер вектора `[n x 1]`.<BR>
|
||||
Память должна быть выделена.<BR>
|
||||
Если указатель `NULL`, то рассчет АЧХ не производится.<BR><BR>
|
||||
|
||||
\param[out] phi Указатель на вектор ФЧХ.<BR>
|
||||
Размер вектора `[n x 1]`.<BR>
|
||||
Память должна быть выделена.<BR>
|
||||
Если указатель `NULL`, то рассчет ФЧХ не производится.<BR><BR>
|
||||
|
||||
\param[out] tau Указатель на вектор ГВЗ.<BR>
|
||||
Размер вектора `[n x 1]`.<BR>
|
||||
Память должна быть выделена.<BR>
|
||||
Если указатель `NULL`, то рассчет ГВЗ не производится.<BR><BR>
|
||||
|
||||
Пример использования функции `freqs_resp`:
|
||||
|
||||
|
||||
\include butter_ap_test.c
|
||||
|
||||
Результат работы программы:
|
||||
|
||||
\verbatim
|
||||
b[ 0] = 1.002 a[ 0] = 1.002
|
||||
b[ 1] = 0.000 a[ 1] = 2.618
|
||||
b[ 2] = 0.000 a[ 2] = 3.418
|
||||
b[ 3] = 0.000 a[ 3] = 2.615
|
||||
b[ 4] = 0.000 a[ 4] = 1.000
|
||||
\endverbatim
|
||||
|
||||
<BR><BR>
|
||||
В каталоге `dat` будут созданы три файла:<BR>
|
||||
|
||||
<pre>
|
||||
butter_ap_test_mag.txt АЧХ фильтра
|
||||
butter_ap_test_phi.txt ФЧХ фильтра
|
||||
butter_ap_test_tau.txt ГВЗ фильтра
|
||||
</pre>
|
||||
|
||||
Кроме того программа GNUPLOT произведет построение следующих графиков по сохраненным в файлах данным:
|
||||
|
||||
АЧХ фильтра: `butter_ap_test_mag.png`
|
||||
\image html butter_ap_test_mag.png
|
||||
|
||||
ФЧХ фильтра: `butter_ap_test_phi.png`
|
||||
\image html butter_ap_test_phi.png
|
||||
|
||||
ГВЗ фильтра: `butter_ap_test_tau.png`
|
||||
\image html butter_ap_test_tau.png
|
||||
|
||||
|
||||
|
||||
\return
|
||||
`RES_OK` Параметры фильтра рассчитаны успешно.<BR>
|
||||
В противном случае \ref ERROR_CODE_GROUP "код ошибки".<BR>
|
||||
|
||||
\author
|
||||
Бахурин Сергей
|
||||
www.dsplib.org
|
||||
|
||||
**************************************************************************************************** */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*! ************************************************************************************************
|
||||
\ingroup FILTER_ANALYSIS_GROUP
|
||||
\fn int freqz(double* b, double* a, int ord, double* w, int n, complex_t *h)
|
||||
|
|
|
@ -93,6 +93,109 @@ exit_label:
|
|||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
Magnitude, phase response and group delay of an analog filter H(s)
|
||||
***************************************************************************************************/
|
||||
int DSPL_API freqs_resp(double* b, double* a, int ord, double* w, int n, int flag,
|
||||
double *h, double* phi, double* tau)
|
||||
{
|
||||
int res, k;
|
||||
|
||||
complex_t *hc = NULL;
|
||||
double *phi0 = NULL;
|
||||
double *phi1 = NULL;
|
||||
double *w0 = NULL;
|
||||
double *w1 = NULL;
|
||||
|
||||
if(!b || !a || !w)
|
||||
return ERROR_PTR;
|
||||
if(ord < 1)
|
||||
return ERROR_FILTER_ORD;
|
||||
if(n < 1)
|
||||
return ERROR_SIZE;
|
||||
|
||||
|
||||
hc = (complex_t*) malloc (n*sizeof(complex_t));
|
||||
res = freqs(b, a, ord, w, n, hc);
|
||||
if(res != RES_OK)
|
||||
goto exit_label;
|
||||
|
||||
|
||||
if(h)
|
||||
{
|
||||
if(flag & DSPL_FLAG_LOG)
|
||||
{
|
||||
for(k = 0; k < n; k++)
|
||||
h[k] = 10.0 * log10(ABSSQR(hc[k]));
|
||||
}
|
||||
else
|
||||
{
|
||||
for(k = 0; k < n; k++)
|
||||
h[k] = sqrt(ABSSQR(hc[k]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(phi)
|
||||
{
|
||||
for(k = 0; k < n; k++)
|
||||
phi[k] = atan2(IM(hc[k]), RE(hc[k]));
|
||||
|
||||
if(flag & DSPL_FLAG_UNWRAP)
|
||||
{
|
||||
res = unwrap(phi, n, M_2PI, 0.8);
|
||||
if(res != RES_OK)
|
||||
goto exit_label;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(tau)
|
||||
{
|
||||
phi0 = (double*) malloc(n*sizeof(double));
|
||||
phi1 = (double*) malloc(n*sizeof(double));
|
||||
w0 = (double*) malloc(n*sizeof(double));
|
||||
w1 = (double*) malloc(n*sizeof(double));
|
||||
|
||||
w0[0] = w[0] - (w[1] - w[0])*0.02;
|
||||
w1[0] = w[0] + (w[1] - w[0])*0.02;
|
||||
|
||||
for(k = 1; k < n; k++)
|
||||
{
|
||||
w0[k] = w[k] - (w[k] - w[k-1])*0.02;
|
||||
w1[k] = w[k] + (w[k] - w[k-1])*0.02;
|
||||
}
|
||||
res = freqs_resp(b, a, ord, w0, n, DSPL_FLAG_UNWRAP, NULL, phi0, NULL);
|
||||
if(res != RES_OK)
|
||||
goto exit_label;
|
||||
res = freqs_resp(b, a, ord, w1, n, DSPL_FLAG_UNWRAP, NULL, phi1, NULL);
|
||||
if(res != RES_OK)
|
||||
goto exit_label;
|
||||
for(k = 0; k < n; k++)
|
||||
tau[k] = (phi0[k] - phi1[k])/(w1[k] - w0[k]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
exit_label:
|
||||
if(hc)
|
||||
free(hc);
|
||||
if(phi0)
|
||||
free(phi0);
|
||||
if(phi1)
|
||||
free(phi1);
|
||||
if(w0)
|
||||
free(w0);
|
||||
if(w1)
|
||||
free(w1);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
Complex frequency response of a digital filter H(z)
|
||||
|
@ -168,4 +271,62 @@ exit_label:
|
|||
if(ac)
|
||||
free(ac);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
Unwrap function
|
||||
**************************************************************************************************/
|
||||
int DSPL_API unwrap(double* phi, int n, double lev, double mar)
|
||||
{
|
||||
double a[2] = {0.0, 0.0};
|
||||
double d;
|
||||
double th;
|
||||
int k;
|
||||
int flag = 1;
|
||||
|
||||
|
||||
if(!phi)
|
||||
return ERROR_PTR;
|
||||
|
||||
if(n<1)
|
||||
return ERROR_SIZE;
|
||||
|
||||
if(lev<=0 || mar <=0)
|
||||
return ERROR_UNWRAP;
|
||||
|
||||
th = mar*lev;
|
||||
while(flag)
|
||||
{
|
||||
flag = 0;
|
||||
a[0] = a[1] = 0.0;
|
||||
for(k = 0; k<n-1; k++)
|
||||
{
|
||||
d = phi[k+1] - phi[k];
|
||||
if( d > th)
|
||||
{
|
||||
a[0] -= lev;
|
||||
flag = 1;
|
||||
}
|
||||
if( d < -th)
|
||||
{
|
||||
a[0] += lev;
|
||||
flag = 1;
|
||||
}
|
||||
phi[k]+=a[1];
|
||||
a[1] = a[0];
|
||||
}
|
||||
phi[n-1]+=a[1];
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -181,7 +181,6 @@ Analog Normalized Chebyshev type 1 filter zeros and poles
|
|||
***************************************************************************************************/
|
||||
int DSPL_API cheby1_ap_zp(int ord, double rp, complex_t *z, int* nz, complex_t *p, int* np)
|
||||
{
|
||||
double alpha;
|
||||
double theta;
|
||||
double ep;
|
||||
double beta;
|
||||
|
|
|
@ -65,6 +65,7 @@ p_flipip_cmplx flipip_cmplx ;
|
|||
p_fourier_series_dec fourier_series_dec ;
|
||||
p_fourier_series_rec fourier_series_rec ;
|
||||
p_freqs freqs ;
|
||||
p_freqs_resp freqs_resp ;
|
||||
p_freqz freqz ;
|
||||
p_goertzel goertzel ;
|
||||
p_goertzel_cmplx goertzel_cmplx ;
|
||||
|
@ -82,6 +83,7 @@ p_sin_cmplx sin_cmplx ;
|
|||
p_sqrt_cmplx sqrt_cmplx ;
|
||||
p_trapint trapint ;
|
||||
p_trapint_cmplx trapint_cmplx ;
|
||||
p_unwrap unwrap ;
|
||||
p_writebin writebin ;
|
||||
p_writetxt writetxt ;
|
||||
|
||||
|
@ -166,6 +168,7 @@ void* dspl_load()
|
|||
LOAD_FUNC(fourier_series_rec);
|
||||
LOAD_FUNC(freqz);
|
||||
LOAD_FUNC(freqs);
|
||||
LOAD_FUNC(freqs_resp);
|
||||
LOAD_FUNC(goertzel);
|
||||
LOAD_FUNC(goertzel_cmplx);
|
||||
LOAD_FUNC(linspace);
|
||||
|
@ -182,6 +185,7 @@ void* dspl_load()
|
|||
LOAD_FUNC(sqrt_cmplx);
|
||||
LOAD_FUNC(trapint);
|
||||
LOAD_FUNC(trapint_cmplx);
|
||||
LOAD_FUNC(unwrap);
|
||||
LOAD_FUNC(writebin);
|
||||
LOAD_FUNC(writetxt);
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ typedef struct
|
|||
#define ERROR_SYM_TYPE 0x19251320
|
||||
/* T 0x20xxxxxx*/
|
||||
/* U 0x21xxxxxx*/
|
||||
#define ERROR_UNWRAP 0x21142318
|
||||
/* V 0x22xxxxxx*/
|
||||
/* W 0x23xxxxxx*/
|
||||
#define ERROR_WIN_TYPE 0x23092025
|
||||
|
@ -132,6 +133,10 @@ typedef struct
|
|||
#define DSPL_SYMMETRIC 0x00000000
|
||||
#define DSPL_PERIODIC 0x00000001
|
||||
|
||||
|
||||
#define DSPL_FLAG_LOG 0x00000001
|
||||
#define DSPL_FLAG_UNWRAP 0x00000002
|
||||
|
||||
#define DSPL_WIN_SYM_MASK 0x00000001
|
||||
#define DSPL_WIN_MASK 0x000FFFFE
|
||||
|
||||
|
@ -194,10 +199,8 @@ extern "C" {
|
|||
|
||||
DECLARE_FUNC(int, acos_cmplx, complex_t* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, asin_cmplx, complex_t* COMMA int COMMA complex_t*);
|
||||
|
||||
DECLARE_FUNC(int, butter_ap, double COMMA int COMMA double* COMMA double*);
|
||||
DECLARE_FUNC(int, butter_ap_zp, int COMMA double COMMA complex_t* COMMA int* COMMA complex_t* COMMA int*);
|
||||
|
||||
DECLARE_FUNC(int, cheby_poly1, double* COMMA int COMMA int COMMA double*);
|
||||
DECLARE_FUNC(int, cheby_poly2, double* COMMA int COMMA int COMMA double*);
|
||||
DECLARE_FUNC(int, cheby1_ap, double COMMA int COMMA double* COMMA double*);
|
||||
|
@ -214,7 +217,6 @@ DECLARE_FUNC(int, farrow_lagrange, double* COMMA int COMMA double
|
|||
DECLARE_FUNC(int, farrow_spline, double* COMMA int COMMA double COMMA double COMMA double COMMA double** COMMA int*);
|
||||
DECLARE_FUNC(int, filter_iir, double* COMMA double* COMMA int COMMA double* COMMA int COMMA double*);
|
||||
DECLARE_FUNC(int, filter_zp2ab, complex_t* COMMA int COMMA complex_t* COMMA int COMMA int COMMA double* COMMA double*);
|
||||
|
||||
DECLARE_FUNC(int, fft, double* COMMA int COMMA fft_t* COMMA complex_t* );
|
||||
DECLARE_FUNC(int, fft_cmplx, complex_t* COMMA int COMMA fft_t* COMMA complex_t* );
|
||||
DECLARE_FUNC(int, fft_create, fft_t* COMMA int);
|
||||
|
@ -225,6 +227,7 @@ DECLARE_FUNC(int, flipip_cmplx, complex_t* COMMA int);
|
|||
DECLARE_FUNC(int, fourier_series_dec, double* COMMA double* COMMA int COMMA double COMMA int COMMA double* COMMA complex_t*);
|
||||
DECLARE_FUNC(int, fourier_series_rec, double* COMMA complex_t* COMMA int COMMA double* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, freqs, double* COMMA double* COMMA int COMMA double* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, freqs_resp, double* COMMA double* COMMA int COMMA double* COMMA int COMMA int COMMA double* COMMA double* COMMA double*);
|
||||
DECLARE_FUNC(int, freqz, double* COMMA double* COMMA int COMMA double* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, goertzel, double* COMMA int COMMA int* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, goertzel_cmplx, complex_t* COMMA int COMMA int* COMMA int COMMA complex_t*);
|
||||
|
@ -242,6 +245,7 @@ DECLARE_FUNC(int, sin_cmplx, complex_t* COMMA int COMMA comple
|
|||
DECLARE_FUNC(int, sqrt_cmplx, complex_t* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, trapint, double* COMMA double* COMMA int COMMA double* sum);
|
||||
DECLARE_FUNC(int, trapint_cmplx, double* COMMA complex_t* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, unwrap, double* COMMA int COMMA double COMMA double);
|
||||
DECLARE_FUNC(int, writebin, void* COMMA int COMMA int COMMA char*);
|
||||
DECLARE_FUNC(int, writetxt, double* COMMA double* COMMA int COMMA char*);
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ p_flipip_cmplx flipip_cmplx ;
|
|||
p_fourier_series_dec fourier_series_dec ;
|
||||
p_fourier_series_rec fourier_series_rec ;
|
||||
p_freqs freqs ;
|
||||
p_freqs_resp freqs_resp ;
|
||||
p_freqz freqz ;
|
||||
p_goertzel goertzel ;
|
||||
p_goertzel_cmplx goertzel_cmplx ;
|
||||
|
@ -82,6 +83,7 @@ p_sin_cmplx sin_cmplx ;
|
|||
p_sqrt_cmplx sqrt_cmplx ;
|
||||
p_trapint trapint ;
|
||||
p_trapint_cmplx trapint_cmplx ;
|
||||
p_unwrap unwrap ;
|
||||
p_writebin writebin ;
|
||||
p_writetxt writetxt ;
|
||||
|
||||
|
@ -166,6 +168,7 @@ void* dspl_load()
|
|||
LOAD_FUNC(fourier_series_rec);
|
||||
LOAD_FUNC(freqz);
|
||||
LOAD_FUNC(freqs);
|
||||
LOAD_FUNC(freqs_resp);
|
||||
LOAD_FUNC(goertzel);
|
||||
LOAD_FUNC(goertzel_cmplx);
|
||||
LOAD_FUNC(linspace);
|
||||
|
@ -182,6 +185,7 @@ void* dspl_load()
|
|||
LOAD_FUNC(sqrt_cmplx);
|
||||
LOAD_FUNC(trapint);
|
||||
LOAD_FUNC(trapint_cmplx);
|
||||
LOAD_FUNC(unwrap);
|
||||
LOAD_FUNC(writebin);
|
||||
LOAD_FUNC(writetxt);
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ typedef struct
|
|||
#define ERROR_SYM_TYPE 0x19251320
|
||||
/* T 0x20xxxxxx*/
|
||||
/* U 0x21xxxxxx*/
|
||||
#define ERROR_UNWRAP 0x21142318
|
||||
/* V 0x22xxxxxx*/
|
||||
/* W 0x23xxxxxx*/
|
||||
#define ERROR_WIN_TYPE 0x23092025
|
||||
|
@ -132,6 +133,10 @@ typedef struct
|
|||
#define DSPL_SYMMETRIC 0x00000000
|
||||
#define DSPL_PERIODIC 0x00000001
|
||||
|
||||
|
||||
#define DSPL_FLAG_LOG 0x00000001
|
||||
#define DSPL_FLAG_UNWRAP 0x00000002
|
||||
|
||||
#define DSPL_WIN_SYM_MASK 0x00000001
|
||||
#define DSPL_WIN_MASK 0x000FFFFE
|
||||
|
||||
|
@ -194,10 +199,8 @@ extern "C" {
|
|||
|
||||
DECLARE_FUNC(int, acos_cmplx, complex_t* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, asin_cmplx, complex_t* COMMA int COMMA complex_t*);
|
||||
|
||||
DECLARE_FUNC(int, butter_ap, double COMMA int COMMA double* COMMA double*);
|
||||
DECLARE_FUNC(int, butter_ap_zp, int COMMA double COMMA complex_t* COMMA int* COMMA complex_t* COMMA int*);
|
||||
|
||||
DECLARE_FUNC(int, cheby_poly1, double* COMMA int COMMA int COMMA double*);
|
||||
DECLARE_FUNC(int, cheby_poly2, double* COMMA int COMMA int COMMA double*);
|
||||
DECLARE_FUNC(int, cheby1_ap, double COMMA int COMMA double* COMMA double*);
|
||||
|
@ -214,7 +217,6 @@ DECLARE_FUNC(int, farrow_lagrange, double* COMMA int COMMA double
|
|||
DECLARE_FUNC(int, farrow_spline, double* COMMA int COMMA double COMMA double COMMA double COMMA double** COMMA int*);
|
||||
DECLARE_FUNC(int, filter_iir, double* COMMA double* COMMA int COMMA double* COMMA int COMMA double*);
|
||||
DECLARE_FUNC(int, filter_zp2ab, complex_t* COMMA int COMMA complex_t* COMMA int COMMA int COMMA double* COMMA double*);
|
||||
|
||||
DECLARE_FUNC(int, fft, double* COMMA int COMMA fft_t* COMMA complex_t* );
|
||||
DECLARE_FUNC(int, fft_cmplx, complex_t* COMMA int COMMA fft_t* COMMA complex_t* );
|
||||
DECLARE_FUNC(int, fft_create, fft_t* COMMA int);
|
||||
|
@ -225,6 +227,7 @@ DECLARE_FUNC(int, flipip_cmplx, complex_t* COMMA int);
|
|||
DECLARE_FUNC(int, fourier_series_dec, double* COMMA double* COMMA int COMMA double COMMA int COMMA double* COMMA complex_t*);
|
||||
DECLARE_FUNC(int, fourier_series_rec, double* COMMA complex_t* COMMA int COMMA double* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, freqs, double* COMMA double* COMMA int COMMA double* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, freqs_resp, double* COMMA double* COMMA int COMMA double* COMMA int COMMA int COMMA double* COMMA double* COMMA double*);
|
||||
DECLARE_FUNC(int, freqz, double* COMMA double* COMMA int COMMA double* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, goertzel, double* COMMA int COMMA int* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, goertzel_cmplx, complex_t* COMMA int COMMA int* COMMA int COMMA complex_t*);
|
||||
|
@ -242,6 +245,7 @@ DECLARE_FUNC(int, sin_cmplx, complex_t* COMMA int COMMA comple
|
|||
DECLARE_FUNC(int, sqrt_cmplx, complex_t* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, trapint, double* COMMA double* COMMA int COMMA double* sum);
|
||||
DECLARE_FUNC(int, trapint_cmplx, double* COMMA complex_t* COMMA int COMMA complex_t*);
|
||||
DECLARE_FUNC(int, unwrap, double* COMMA int COMMA double COMMA double);
|
||||
DECLARE_FUNC(int, writebin, void* COMMA int COMMA int COMMA char*);
|
||||
DECLARE_FUNC(int, writetxt, double* COMMA double* COMMA int COMMA char*);
|
||||
|
||||
|
|
|
@ -1,8 +1,34 @@
|
|||
|
||||
set logscale x
|
||||
unset key
|
||||
set grid
|
||||
set xlabel "frequency, rad/s"
|
||||
|
||||
set lmargin at screen 0.10
|
||||
|
||||
|
||||
set terminal pngcairo size 560,420 enhanced font 'Verdana,8'
|
||||
set output 'img/butter_ap_test_mag.png'
|
||||
set ylabel "Butterworth filter magnitude, dB"
|
||||
set yrange [-100:5]
|
||||
plot 'dat/butter_ap_test_mag.txt' with lines
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
set terminal pngcairo size 560,420 enhanced font 'Verdana,8'
|
||||
set output 'img/butter_ap_test_phi.png'
|
||||
|
||||
set ylabel "Butterworth filter phase response, rad"
|
||||
unset yrange
|
||||
plot 'dat/butter_ap_test_phi.txt' with lines
|
||||
|
||||
|
||||
|
||||
|
||||
set terminal pngcairo size 560,420 enhanced font 'Verdana,8'
|
||||
set output 'img/butter_ap_test_tau.png'
|
||||
|
||||
set ylabel "Butterworth filter groupdelay, sec"
|
||||
unset yrange
|
||||
plot 'dat/butter_ap_test_tau.txt' with lines
|
||||
|
|
|
@ -1,8 +1,28 @@
|
|||
|
||||
set logscale x
|
||||
unset key
|
||||
set grid
|
||||
set xlabel "frequency, rad/s"
|
||||
|
||||
set lmargin at screen 0.10
|
||||
|
||||
set terminal pngcairo size 560,420 enhanced font 'Verdana,8'
|
||||
set output 'img/cheby1_ap_test_mag.png'
|
||||
set ylabel "Chebyshev type 1 filter magnitude, dB"
|
||||
set yrange [-100:5]
|
||||
plot 'dat/cheby1_ap_test_mag.txt' with lines
|
||||
|
||||
|
||||
set terminal pngcairo size 560,420 enhanced font 'Verdana,8'
|
||||
set output 'img/cheby1_ap_test_phi.png'
|
||||
|
||||
set ylabel "Chebyshev type 1 filter phase response, rad"
|
||||
unset yrange
|
||||
plot 'dat/cheby1_ap_test_phi.txt' with lines
|
||||
|
||||
|
||||
set terminal pngcairo size 560,420 enhanced font 'Verdana,8'
|
||||
set output 'img/cheby1_ap_test_tau.png'
|
||||
|
||||
set ylabel "Chebyshev type 1 filter groupdelay, sec"
|
||||
unset yrange
|
||||
plot 'dat/cheby1_ap_test_tau.txt' with lines
|
||||
|
|
Przed Szerokość: | Wysokość: | Rozmiar: 21 KiB Po Szerokość: | Wysokość: | Rozmiar: 15 KiB |
Po Szerokość: | Wysokość: | Rozmiar: 16 KiB |
Po Szerokość: | Wysokość: | Rozmiar: 17 KiB |
Przed Szerokość: | Wysokość: | Rozmiar: 22 KiB Po Szerokość: | Wysokość: | Rozmiar: 16 KiB |
Po Szerokość: | Wysokość: | Rozmiar: 16 KiB |
Po Szerokość: | Wysokość: | Rozmiar: 18 KiB |
|
@ -12,8 +12,10 @@ int main()
|
|||
void* handle; // DSPL handle
|
||||
handle = dspl_load(); // Load DSPL function
|
||||
|
||||
double a[ORD+1], b[ORD+1];
|
||||
double a[ORD+1], b[ORD+1];
|
||||
double Rp = 3.0;
|
||||
double w[N], mag[N], phi[N], tau[N];
|
||||
|
||||
|
||||
int k;
|
||||
int res = butter_ap(Rp, ORD, b, a);
|
||||
|
@ -24,19 +26,16 @@ int main()
|
|||
printf("b[%2d] = %9.3f a[%2d] = %9.3f\n", k, b[k], k, a[k]);
|
||||
|
||||
|
||||
double w[N], hdb[N];
|
||||
complex_t h[N];
|
||||
|
||||
logspace(-2.0, 2.0, N , DSPL_SYMMETRIC, w);
|
||||
freqs(b, a, ORD, w, N, h);
|
||||
for(k = 0; k < N; k++)
|
||||
hdb[k] = 10.0 * log10(ABSSQR(h[k]));
|
||||
freqs_resp(b, a, ORD, w, N, DSPL_FLAG_LOG|DSPL_FLAG_UNWRAP, mag, phi, tau);
|
||||
|
||||
writetxt(w, mag, N, "dat/butter_ap_test_mag.txt");
|
||||
writetxt(w, phi, N, "dat/butter_ap_test_phi.txt");
|
||||
writetxt(w, tau, N, "dat/butter_ap_test_tau.txt");
|
||||
|
||||
writetxt(w, hdb, N, "dat/butter_ap_test_mag.txt");
|
||||
|
||||
dspl_free(handle); // free dspl handle
|
||||
|
||||
system("gnuplot -p gnuplot/butter_ap_test.plt");
|
||||
res = system("gnuplot gnuplot/butter_ap_test.plt");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,8 +12,10 @@ int main()
|
|||
void* handle; // DSPL handle
|
||||
handle = dspl_load(); // Load DSPL function
|
||||
|
||||
double a[ORD+1], b[ORD+1];
|
||||
double a[ORD+1], b[ORD+1];
|
||||
double Rp = 3.0;
|
||||
double w[N], mag[N], phi[N], tau[N];
|
||||
|
||||
|
||||
int k;
|
||||
int res = cheby1_ap(Rp, ORD, b, a);
|
||||
|
@ -24,19 +26,16 @@ int main()
|
|||
printf("b[%2d] = %9.3f a[%2d] = %9.3f\n", k, b[k], k, a[k]);
|
||||
|
||||
|
||||
double w[N], hdb[N];
|
||||
complex_t h[N];
|
||||
|
||||
logspace(-2.0, 2.0, N , DSPL_SYMMETRIC, w);
|
||||
freqs(b, a, ORD, w, N, h);
|
||||
for(k = 0; k < N; k++)
|
||||
hdb[k] = 10.0 * log10(ABSSQR(h[k]));
|
||||
freqs_resp(b, a, ORD, w, N, DSPL_FLAG_LOG|DSPL_FLAG_UNWRAP, mag, phi, tau);
|
||||
|
||||
writetxt(w, mag, N, "dat/cheby1_ap_test_mag.txt");
|
||||
writetxt(w, phi, N, "dat/cheby1_ap_test_phi.txt");
|
||||
writetxt(w, tau, N, "dat/cheby1_ap_test_tau.txt");
|
||||
|
||||
writetxt(w, hdb, N, "dat/cheby1_ap_test_mag.txt");
|
||||
|
||||
dspl_free(handle); // free dspl handle
|
||||
|
||||
system("gnuplot -p gnuplot/cheby1_ap_test.plt");
|
||||
res = system("gnuplot gnuplot/cheby1_ap_test.plt");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|