Для работы с нерекурсивными цифровыми
фильтрами в приложении созданы вспомогательные классы: TflrtBuff – реализует буфер (сдвиговый
регистр), TFIRFltr – реализует непосредственно фильтр, объявлены также типы
TFloatBuffer и PFloatBuffer.
Рассмотрим непосредственно пример
использования.
Создадим экземпляр класса:
FIRFlrt:=TFIRFltr.Create(FLEN); Конструктор принимает один параметр:
размерность (длинна) фильтра.
Следует отметить, что чем выше
размерность – тем выше подавление (или усиление) частот (можно назвать это
качеством фильтрации), но и связано с внесением фазовых искажений :)
На следующем шаге записываем значения
коэффициентов фильтра.
FIRFlrt.addCoef(0.544218); FIRFlrt.addCoef(0.315244); FIRFlrt.addCoef(-0.043651); FIRFlrt.addCoef(-0.097022); FIRFlrt.addCoef(0.041977); FIRFlrt.addCoef(0.048913); FIRFlrt.addCoef(-0.039273); FIRFlrt.addCoef(-0.025616); FIRFlrt.addCoef(0.035662); FIRFlrt.addCoef(0.011145); FIRFlrt.addCoef(-0.031307).
Значения рассчитаны в программе NUMERI (можно использовать и другие).
Выведем на форму исходный сигнал (для
синуса 100Гц и 3800Гц):
for i:=0 to DATALEN-1 do //формируем данные и их
визуализируем begin smpl :=
10000*(sin(100*2*i/Pi)+sin(3800*2*i/Pi)); tmpX := Round(i*PaintBoxSngl.Width/DATALEN); tmpY := PaintBoxSngl.Height div 2 - Round(
smpl / 400 {масштабный коэффициент}); PaintBoxSngl.Canvas.LineTo(tmpX, tmpY); end;
И непосредственно фильтрация (фильтр
НЧ):
for i:=0 to DATALEN-1 do //формируем данные и их
визуализируем begin smpl :=
10000*(sin(800*2*i/Pi)+sin(3800*2*i/Pi)); tmpX :=
Round(i*PaintBoxSnglFltrLo.Width/DATALEN); tmpY := PaintBoxSnglFltrLo.Height div 2 -
Round(FIRFlrt.proccessSample(smpl) /
50 {масштабный коэффициент}); PaintBoxSnglFltrLo.Canvas.LineTo(tmpX,
tmpY); end;
FIRFlrt.proccessSample(smpl) – здесь происходит фильтрация :)
Очистим список коэффициентов,
заполним коэффициентами для фильтра ВЧ и повторим снова:
FIRFlrt.ClearCoef; //очистить буфер коэффициентов FIRFlrt.addCoef(0.455782); FIRFlrt.addCoef(-0.315244); FIRFlrt.addCoef(0.043651); FIRFlrt.addCoef(0.097022); FIRFlrt.addCoef(-0.041977); FIRFlrt.addCoef(-0.048913); FIRFlrt.addCoef(0.039273); FIRFlrt.addCoef(0.025616); FIRFlrt.addCoef(-0.035662); FIRFlrt.addCoef(-0.011145); FIRFlrt.addCoef(0.031307);
for i:=0 to DATALEN-1 do //формируем данные и их
визуализируем begin smpl :=
10000*(sin(800*2*i/Pi)+sin(3800*2*i/Pi)); tmpX :=
Round(i*PaintBoxSnglFltrLo.Width/DATALEN); tmpY := PaintBoxSnglFltrHi.Height div 2 -
Round(FIRFlrt.proccessSample(smpl) /
50 {масштабный коэффициент}); PaintBoxSnglFltrHi.Canvas.LineTo(tmpX,
tmpY); end;
FIRFlrt.proccessSample(smpl) – здесь происходит фильтрация J
PaintBoxSngl – PaintBox для вывода сигнала исходного. PaintBoxSnglFltrLo – PaintBox для вывода сигнала отфильтрованного
фильтром НЧ. PaintBoxSnglFltrHi – PaintBox для вывода сигнала отфильтрованного
фильтром ВЧ.
Качайте исходник, программы для
расчета коэффициентов и экспериментируйте !
|