Вот, опять нарвался. Я (для начала) считаю БИХ-обработанный сигнал так:
Код: Выделить всё
// process a sample
inline double iirf(double sample)
{
double sum_i = sample;
double sum_o = 0.0;
int k = m_ix;
int i;
for(i = 0; i < m_nord; ++i)
{
if(0 == k)
k = m_nord;
--k;
sum_i += m_z[k] * m_c[i];
sum_o += m_z[k] * m_d[i];
}
m_z[m_ix] = sum_i;
if(++m_ix >= m_nord) // m_ix = (++m_ix) % m_nord; -- it's BAD for iNTEL
m_ix = 0;
return sum_i * m_d0 + sum_o;
}
Т.е. в лоб реализую каноническую форму. С точки зрения вычислительной эффетивности (ВКЛЮЧАЯ эффективность адресно-индексных выражений) -- это, полагаю, не самый плохой вариант / вероятно -- не лучший, но здесь вынести оценку трудно).
Результат -- КИХ-16-пор.-- ok, т.е. волшебно; но хочется понять предел
.КИХ 19-го порядка -- разваливается. (19-го -- потерян, но, например, такой (термины dsp.dll, разваливается согл. вышеизложенному алг. однозначно):)
Код: Выделить всё
FP fp;
fp.digital = true;
fp.Rp = 2.0;
fp.Rs = 96.0;
fp.type = FB_LOW | FA_ELLIP;
fp.wpl = 0.4999;
fp.wsl = 0.5005;
fp.wph = fp.wsh = 0.0;
Т.е. (1) в инете море вариантов *реализаций* расчета БИХ -- после 2-го не читаю
(2) умный отладчик показывает, что при вычислении выражения "
return sum_i * m_d0 + sum_o;" вычитаются два больших-почти-равных-числа, что есть, по всем канонам точки очень плохо. Т.е., конечно, я, возможно, и справлюсь, [собственно, справился уже -- более скромный КИХ 16-го порядка не только работает, но и устраивает -- просто вопрос о границах IEEE754+IIR-unlim] но, кажется, вопрос "практики БИХ-фильтрации" не только мне м.б. интересен...
И, конечно, очень интересно мнение всех "муки прошедших".
Если ваши решения вам нравятся -- это хорошие решения. И наоборот.