Comments 15
Фильтр всегда надо разбивать на биквадратнные секции, чтобы не иметь гемороя с уходом позиционирования полюсов и нулей. На практике желательно писать в целочисленном формате, а точнее - во fractional. Есть масса тонкостей с минимизацией шума вычислений.
Везде, где я видел описание фильтров, в - это FIR часть коэффициентов, а - это рекурсивная часть (a0 = 1.0).
Если то что обозначено как B[] заценить с точки зрения деградации вычислений то на вскидку выглядит не очень хорошо (засовываем постоянку и смотрим чувствительность от микроприращений).
Фильтр всегда надо разбивать на биквадратнные секции, чтобы не иметь гемороя с уходом позиционирования полюсов и нулей.
если правильно понял, то:
Итоги
Удалось научиться пользоваться двумя разновидностями IIR фильтров нижних частот первого порядка.
разбивать пока нечего.
B [] = { 1.00000000000000000000, -2.99715048309490010000, 2.99430502461701350000, -0.99715453863406001000
Коэффициент А1 я всегда держу меньше 2.0.
Если мы скормим единицы в рекурсивную часть
-2.99715048309490010000, 2.99430502461701350000, -0.99715453863406001000
то для расчета в double все конечно прокатит, но во float все выглядит чуть проблемнее
А у меня везде аккумулятор в биквадрате - это int32_t.
b0, b1, b2, a1 и a2 - int16_t
Вы задали полосу ФНЧ 0,0002% от частоты дискретизации Fs=44000 гц. Верно?
Полоса ФНЧ равна 5 Гц. Длительность переходного процесса такого фильтра составит примерно 1 секунду. Для расчета АЧХ вам надо взять длительность сигнала примерно раз в 10 больше т е примерно 500 000 отсчетов.
Программа Вам написала: уменьшите частоту дискретизации или увеличьте точность расчета коэффициентов. Т е на микропроцессоре вы такой фильтр так просто не сделаете. Да и сигнал такой Вы из-за шумов не увидите.
Так не делается.
----------------
Если Вас реально интересуют лишь частоты ниже 5 Гц, то зачем Вы квантуете сигнал с частотой 44 000 Гц?
Можете попробовать сначала поставить ФНЧ скажем до 100 Гц потом понижаете в цифровом виде частоту дискретизации до 500 Гц и потом считаете свой фильтр да 5 Гц
Частота среза — это такая частота, на которой ослабление фильтра равно -3 дБ в логарифмическом масштабе (в линейном это 0,707).
Это справедливо только для монотонной АЧХ в полосе пропускания.
Для фильтра с пульсациями, например:

такое определение ошибочное.
Полагаю, что правильно будет так:
Частота среза — это такая частота, после которой (для ФНЧ) ослабление фильтра меньше заданного (например -3 дБ в логарифмическом масштабе ,в линейном - 0,707).
Однако надо отметить, что утилита не поможет сгенерировать IIR фильтр нижних частот с малой частотой среза, например 0,0002% от Fs.
Такой крутой срез будет у фильтра очень большого порядка. Очевидно у Вас программа не может рассчитать из-за потери точности вычислений либо неправильного выбора параметров.
Ну программа вам же сказала, что фильтр не стабильный. А нестабильный фильтр - это что? Правильно это генератор. И она вам говорит что надо делать. Вам надо делать вычисления с очень высокой точностью и считать не гладкий фильтр а с пульсациями.
Но по-моему, лучше взять книжку по цифровым фильтрам там обычно есть таблицы и формулы по которым можно определить какой порядок должен быть у фильтра и с какой погрешностью надо вычислять коэффициенты.
собственно реализация простого ФНЧ фильтра выглядит как: Y += (X-Y)*K;
при желании более высоких порядков можно просто дальше каскадировать, даже не пересчитывая коэффициенты в отдельные a[],b[], Z += (Y-Z)*K;
Недостатки цифровых IIR фильтров -IIR фильтр порой усиливает сигнал.
Это не недостаток IR фильтров, это кривая программа для расчёта. Коэффициент усиления фильтра регулируется просто масштабированием всех коэффициентов знаменателя. Действительные недостатки IIR фильтров это:
а) невозможность получить линейную ФЧХ;
б) численная неустойчивость на порядках больше 2 даже с арифметикой повышенной точности. Поэтому их и разбивают на биквадратные секции.
Как то вы совсем примитивно изложили про фильтры. Обычно для разработчика задача сложнее. Что, если в программе не нужен заранее рассчитанный фильтр, а нужен настраиваемый через параметры? WinFilter и прочие калькуляторы вам тут не помогут. В своем проекте я делал через биквадратные FIR-фильтры где в базе 2nd order s-domain function (p0 + p1*s + p2*s^2)/(q0 + q1*s + q2*s^2) и разные типы фильтров заполняют коэффициенты p, q. Так можно сделать HPF, LPF, Notch, Lag compensator, band-pass и прочие.
Далее переводим в decrete-time domain (одинаково для всех типов) для выбранной частоты сэмплирования и получаем рекуррентные соотношения. Для бОльших порядков можно каскадировать, чтобы не усложнять математику и ограничиться float (на простых микропроцессорах это оптимально)
Синтез Цифрового БИХ Фильтра Низких Частот