|
|
  |
Реализация БИХ фильтра, что делать с С-Header из MATLAB ? |
|
|
|
Apr 26 2010, 10:05
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 20-09-08
Пользователь №: 40 347

|
Цитата(sysel @ Apr 26 2010, 11:49)  Поделитесь, пожалуйста, рабочим кодом. Код typedef struct structIIR{ double* b; int lb; double* a; int la; }IIR, *PIIR;
int conv(double *a, int la, double *b, int lb, double *c){ if((!a)||(!b)||(!c)||(!la)||(!lb)) return 0; memset(c, 0, (la+lb-1)*sizeof(double)); for(int i = 0; i < la; i++){ for(int j = 0; j < lb; j++) c[i+j] += a[i]*b[j]; } return 1; }
int iir_filter(PIIR piir, double *s, int n){ double* c = (double*)malloc(piir->la*sizeof(double)); double* d = (double*)malloc(piir->lb*sizeof(double)); double* v = (double*)malloc((piir->lb+n-1)*sizeof(double));
for(int i =0; i<piir->la; i++) c[i] = piir->a[i]/piir->a[0]; for(int i =0; i<piir->lb; i++) d[i] = piir->b[i]/piir->a[0]; conv(d,piir->lb,s,n,v); s[0] = v[0]; for(int i = 1; i<n; i++){ int k = 1; s[i] = v[i]; while(((i-k)>=0)&&(k<piir->la)){ s[i]-=c[k]*s[i-k]; k++; } } free(c); free(d); free(v); return 1; } Коэффициенты пишем в структуру IIR и указатель на нее в функцию фильтрации. А вообще вот dll весит 20 кБ умеет считать фильтры аналогично матлабу. Есть документация с примерами.
Сообщение отредактировал bahurin - Apr 26 2010, 10:07
|
|
|
|
|
Apr 26 2010, 12:46
|

Знающий
   
Группа: Свой
Сообщений: 601
Регистрация: 3-07-07
Пользователь №: 28 852

|
Разобрался сам. Добавлю свои результаты в фонд будущих поколений: Пусть нам FDATOOL выдала следующий C-header: Код /* * Filter Coefficients (C Source) generated by the Filter Design and Analysis Tool * * Generated by MATLAB(R) 7.8 and the Signal Processing Toolbox 6.11. * * Generated on: 26-Apr-2010 15:26:51 * */
/* * Discrete-Time IIR Filter (real) * ------------------------------- * Filter Structure : Direct-Form II, Second-Order Sections * Number of Sections : 3 * Stable : Yes * Linear Phase : No */
/* General type conversion for MATLAB generated C-code */ #include "tmwtypes.h" /* * Expected path to tmwtypes.h * C:\Program Files\MATLAB\R2009a\extern\include\tmwtypes.h */ #define MWSPT_NSEC 7 const int NL[MWSPT_NSEC] = { 1,3,1,3,1,2,1 }; const real64_T NUM[MWSPT_NSEC][3] = { { 0.001582012905215, 0, 0 }, { 1, -1.997425031815, 1 }, { 0.06078064837324, 0, 0 }, { 1, -1.998996713475, 1 }, { 0.007688806860118, 0, 0 }, { 1, 1, 0 }, { 1, 0, 0 } }; const int DL[MWSPT_NSEC] = { 1,3,1,3,1,2,1 }; const real64_T DEN[MWSPT_NSEC][3] = { { 1, 0, 0 }, { 1, -1.996305874613, 0.9963329403565 }, { 1, 0, 0 }, { 1, -1.998581806418, 0.9986427868237 }, { 1, 0, 0 }, { 1, -0.9976855336623, 0 }, { 1, 0, 0 } }; Прячем #include "tmwtypes.h" : // #include "tmwtypes.h" И заменяем "real64_T" на "double". Для получения одного отфильтрованного отсчета сигнала надо вызвать функцию IIR_filt (X), где X - входной отсчет. Функция возвращает отсчет отфильтрованного сигнала. Предварительно надо задать начальные значения для массива "ячеек памяти" WHistory. Ну или просто обнулить их. Код #include "fdacoefs.h"
double WHistory[MWSPT_NSEC][2];
double IIR_filt (double X){ for (int i=0; i<MWSPT_NSEC; i++){ double W; W = X; for (int j=1; j<DL[i]; j++){ W-= DEN[i][j]*WHistory[i][j-1]; }; W*=1/DEN[i][0];
X = W * NUM[i][0]; for (int j=1; j<NL[i]; j++){ X+=NUM[i][j]*WHistory[i][j-1]; }; WHistory[i][1] = WHistory[i][0]; WHistory[i][0] = W; }; return X; }; Код не оптимизирован, зато даёт хорошее представление о том, чиго надо делать с хедером из FDATOOL. Вот схематичное описание того, что далает этот код: http://ftp.math.hkbu.edu.hk/help/toolbox/s...ilt.df2sos.html
|
|
|
|
|
Apr 27 2010, 17:35
|
Частый гость
 
Группа: Участник
Сообщений: 92
Регистрация: 23-12-08
Из: Кишинёв
Пользователь №: 42 680

|
Цитата(sysel @ Apr 27 2010, 12:21)  Код // Блок "Gain" между каскадами фильтра X *= NUM[i][0] * (1/DEN[i][0]); Этот участок кода вызывает подозрение. На fixed-point'е веротно не будет работать(как надо). Наверное лучше разделить: сначала умножение, потом деление. Да и в целом код не выглядит ни оптимальным ни красивым. Сам начал разбираться этим вопросом в последнии дни. Ваши приведённые примеры значительно помогли(мне  ). Странно, но в дебрях матлабовского хэлпа ничего не находится по алгоритму вычисления. А в широком поле интернета только стандартная формула (типа y = w-1*y-1+w-2*y-2, wi = ... ), в которой коэффициентов много меньше чем в сабжевом хидере.
|
|
|
|
|
Apr 28 2010, 06:21
|

Знающий
   
Группа: Свой
Сообщений: 601
Регистрация: 3-07-07
Пользователь №: 28 852

|
Цитата(baralgin @ Apr 27 2010, 21:35)  Этот участок кода вызывает подозрение. На fixed-point'е веротно не будет работать(как надо). Наверное лучше разделить: сначала умножение, потом деление. Да, флагом махать я начал раньше времени насчет "fixed-point". В общем, приведённый выше фрагмент кода работает с fixed-point коеффицентами, если в объявлении матриц коэффиециентов изменить тип на "double". С fixed-point всё не так просто, как мне казалось. FDATOOL выкидывает форматы представления с фиксированной запятой в комментарии, так что породить код, который бы с ходу хавал бы хедер не выйдет. Цитата(baralgin @ Apr 27 2010, 21:35)  Да и в целом код не выглядит ни оптимальным ни красивым. Согласен. Но, думаю, более оптимальный и красивый код можно породить только если вычленить коэффиециенты из матриц NUM и DEN в какие-то другие структуры. И что самое главное, разделить на этапе написания кода блоки "gain" и фильтров. Цитата(baralgin @ Apr 27 2010, 21:35)  Сам начал разбираться этим вопросом в последнии дни. Ваши приведённые примеры значительно помогли(мне  ). Странно, но в дебрях матлабовского хэлпа ничего не находится по алгоритму вычисления. А в широком поле интернета только стандартная формула (типа y = w-1*y-1+w-2*y-2, wi = ... ), в которой коэффициентов много меньше чем в сабжевом хидере. Была та же проблема. Формул куча, кода шиш. Породил какой-никакой код и выложил тут. У приведённого выше кода есть большой плюс: он опирается на порождённый fdatool хедером с минимальными изменениями в нём.
|
|
|
|
|
Oct 20 2011, 12:52
|
Участник

Группа: Участник
Сообщений: 17
Регистрация: 3-02-05
Пользователь №: 2 399

|
Цитата(sysel @ Apr 26 2010, 16:46)  Разобрался сам. Добавлю свои результаты в фонд будущих поколений:
Пусть нам FDATOOL выдала следующий C-header: [code]/* Борюсь с той же проблемой. Если с хидером для FIR еще как-то разобрался, то для IIR самому разобраться не получается. Приведенный пример кода тупо вставленный в программу работает не правильно. Видимо где-то ошибка, где не пойму. Подскажите плиз где глянуть наглядный алгоритм использования коэф-тов из fdatool.
|
|
|
|
|
Jan 13 2012, 17:15
|
Группа: Новичок
Сообщений: 2
Регистрация: 13-01-12
Пользователь №: 69 365

|
столкнулся с похожей проблемой.Нужно реализовать филтер чебишева с данными параметрами на процессоре stm32f101 ( arm cortex m3) .Имеются библиотеки расчёта IIR (ili FIR) филтеров от производителей ARMa (CMSIS - DSP http://www.onarm.com/cmsis/download/).Если кому-то удалось реализовать филтер,используя Матлаб fdatool и исползуя эти библиотеки,поделитесь пожалуста опытом.Спасибо
|
|
|
|
|
Feb 14 2012, 11:17
|
Частый гость
 
Группа: Участник
Сообщений: 181
Регистрация: 26-07-10
Пользователь №: 58 606

|
Цитата(Vl4ever @ Jan 13 2012, 21:15)  столкнулся с похожей проблемой.Нужно реализовать филтер чебишева с данными параметрами на процессоре stm32f101 ( arm cortex m3) .Имеются библиотеки расчёта IIR (ili FIR) филтеров от производителей ARMa (CMSIS - DSP http://www.onarm.com/cmsis/download/).Если кому-то удалось реализовать филтер,используя Матлаб fdatool и исползуя эти библиотеки,поделитесь пожалуста опытом.Спасибо  Посмотрите документ "The Scientist and Engineer's Guide to Digital Signal Processing". Там есть алгоритм расчета коэффициентов фильтра.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|