PlainUser 0 Posted April 28, 2016 (edited) · Report post Использую фильтр 2 порядка. Точнее два-три каскадно включенных таких фильтра float iir_b2o4hz_1_1(float) float iir_b2o4hz_1_2(float) float iir_b2o4hz_1_3(float) /************************************************************** WinFilter version 0.8 http://www.winfilter.20m.com akundert@hotmail.com Filter type: Low Pass Filter model: Bessel Filter order: 2 Sampling Frequency: 8 KHz Cut Frequency: 0.004000 KHz Coefficents Quantization: float Z domain Zeros z = -1.000000 + j 0.000000 z = -1.000000 + j 0.000000 Z domain Poles z = 0.997282 + j -0.001567 z = 0.997282 + j 0.001567 ***************************************************************/ float iir_b2o4hz_1_1(float NewSample) { static float ACoef[2+1] = { 0.00000475623212008441, 0.00000951246424016882, 0.00000475623212008441}; static float BCoef[2+1] = { 1.00000000000000000000, -1.99456353223009740000, 0.99457337504708221000}; static float y[2+1]; //output samples static float x[2+1]; //input samples uint8_t n; //shift the old samples for(n=2; n>0; n--) { x[n] = x[n-1]; y[n] = y[n-1]; } //Calculate the new output x[0] = NewSample; y[0] = ACoef[0] * x[0]; for(n=1; n<=2; n++) y[0] += ACoef[n] * x[n] - BCoef[n] * y[n]; return y[0]; } В процессе прохождения сигнала через фильтр его уровень становится дискретным с дискретой примерно 1.5% Те на входе изменяю сигнал плавно а на выходе ступеньки. Изменив флоаты на даблы все приводится в норму. Но ОЧЕНЬ хочется обойтись флоатами ибо разница в скорости раз в десять. Флоаты это "Single precision data type for IEEE 754 arithmetic" 32бит с мантиссой 23разряда. А 1.5% это всего-лишь 6разрядов. Куда копать? ЗЫ.Коэффициенты пробовал менять типа 0.00000475623212008441 на 0.475623212008441. Не помогло. Даблы 64бит с мантиссой 52бит Edited April 28, 2016 by PlainUser Quote Ответить с цитированием Share this post Link to post Share on other sites
serjj1333 0 Posted April 28, 2016 · Report post static float ACoef[2+1] = { 0.00000475623212008441, 0.00000951246424016882, 0.00000475623212008441}; static float BCoef[2+1] = { 1.00000000000000000000, -1.99456353223009740000, 0.99457337504708221000}; isstable(b,a) в матлабе вернул false для ваших коэффициентов. Наверное стоит пересчитать фильтр? Quote Ответить с цитированием Share this post Link to post Share on other sites
andyp 0 Posted April 28, 2016 · Report post В процессе прохождения сигнала через фильтр его уровень становится дискретным с дискретой примерно 1.5% Те на входе изменяю сигнал плавно а на выходе ступеньки. Изменив флоаты на даблы все приводится в норму. Но ОЧЕНЬ хочется обойтись флоатами ибо разница в скорости раз в десять. Флоаты это "Single precision data type for IEEE 754 arithmetic" 32бит с мантиссой 23разряда. А 1.5% это всего-лишь 6разрядов. Куда копать? ЗЫ.Коэффициенты пробовал менять типа 0.00000475623212008441 на 0.475623212008441. Не помогло. Даблы 64бит с мантиссой 52бит Смотри, твоя реализация фильтра фактически представляет собой каскад (в твоих обозначениях) A(z) * 1/B(z). Коэфф. усиления A в полосе равен -100 dB - здесь ты теряешь точность. Предлагаю перейти к 1/B(z) * A(z) - это т.н. Direct Form II у биквадратной секции. Еще одна опция - снизить частоту дискретизации, чтобы иметь на входе большую относительную полосу сигнала. Есть старинная методичка от Motorolа (прицепил), которая может оказаться полезной. apr7.pdf Quote Ответить с цитированием Share this post Link to post Share on other sites
PlainUser 0 Posted April 28, 2016 (edited) · Report post isstable(b,a) в матлабе вернул false для ваших коэффициентов. Наверное стоит пересчитать фильтр? Объявляю их даблами и все проблемы исчезают. Фильтр работает , все устраивает но считает МЕДЛЕННО. Матлаб не знает цифрового фильтра бесселя потому-что .... http://electronix.ru/forum/index.php?s=&am...t&p=1420966 Пробовал подобный фильтр баттерворта , те-же проблемы с потерей точности. Вот его рассчитывал в матлабе. Могу выложить его. Edited April 28, 2016 by PlainUser Quote Ответить с цитированием Share this post Link to post Share on other sites
andyp 0 Posted April 28, 2016 (edited) · Report post Объявляю их даблами и все проблемы исчезают. Фильтр работает , все устраивает но считает МЕДЛЕННО. Матлаб не знает цифрового фильтра бесселя потому-что .... http://electronix.ru/forum/index.php?s=&am...t&p=1420966 Пробовал подобный фильтр баттерворта , те-же проблемы с потерей точности. Вот его рассчитывал в матлабе. Могу выложить его. Твой фильтр стабилен. Надо просто isstable( a,b ) набирать в матлабе. Проблема в реализованной тобой (ну или пакетом winfilter) структуре фильтра и требованиях к полосе. PS Чтобы как-то ускориться, состояние фильтра нужно держать в регистрах и фильтровать блоками, а не по одному отсчету. Edited April 28, 2016 by andyp Quote Ответить с цитированием Share this post Link to post Share on other sites
serjj1333 0 Posted April 28, 2016 · Report post Твой фильтр стабилен. Надо просто isstable( a,b ) набирать в матлабе. О как. Правда тогда true возвращает, но isstable(a,b) ans = 1 >> isstable(single(a),single(b)) ans = 0 Quote Ответить с цитированием Share this post Link to post Share on other sites
andyp 0 Posted April 28, 2016 · Report post О как. Правда тогда true возвращает, но isstable(a,b) ans = 1 >> isstable(single(a),single(b)) ans = 0 Ничего удивительного с такой-то добротностью как у TC. Поэтому и советовал частоту дискретизации снизить, что увеличит относительную полосу, если Direct Form II не спасет. Quote Ответить с цитированием Share this post Link to post Share on other sites
PlainUser 0 Posted April 28, 2016 · Report post Ничего удивительного с такой-то добротностью как у TC. Поэтому и советовал частоту дискретизации снизить, что увеличит относительную полосу, если Direct Form II не спасет. Снизить частоту дискретизации, такая мысль была но это много хлопот потянет за собой. А как относительная полоса связана с динамическим диапазоном цифирь внутри фильтра? Типа накопление за период Fs / Fc отсчетов происходит? И добавляя к накопленному входной сигнал получаем слишком разные числа и из-за этого теряется точность? Quote Ответить с цитированием Share this post Link to post Share on other sites
andyp 0 Posted April 28, 2016 · Report post Снизить частоту дискретизации, такая мысль была но это много хлопот потянет за собой. А как относительная полоса связана с динамическим диапазоном цифирь внутри фильтра? Типа накопление за период Fs / Fc отсчетов происходит? И добавляя к накопленному входной сигнал получаем слишком разные числа и из-за этого теряется точность? Относительная полоса связана через положение нулей и полюсов передаточной функции фильтра. Твои нули и полюса сейчас просто практически взаимно компенсируют друг друга, отсюда подавление в 100 db в прямой части и усиление в обратной. Расширится полоса - уменьшится добротность, полюса отползут от единичного круга, уменьшится коэфф. передачи. Quote Ответить с цитированием Share this post Link to post Share on other sites