smart_pic 7 6 сентября, 2019 Опубликовано 6 сентября, 2019 (изменено) · Жалоба Продолжаю заниматься фильтрами для ДСП ADAU1701. Фильтры НЧ и ВЧ заработали , Полосовой фильтр работает , но частично. Кроме thermit наверное и помочь некому. В полочных фильтрах добавился непонятный параметр S. не знаю для чего он и как считать его. Ниже код //***************************************************************************** #define M_PI 3.14159265358979323846 #include <math.h> //***************************************************************************** // 1 Расчет коэффициентов для полосового фильтра PeakingFiltr //***************************************************************************** void PeakingFiltr(float f0,float fs,float q,float boost,float gain,float *coeffs) { /* A = 10^(boost/40) w0 = 2*pi*f0/Fs alpha = sin(w0)/(2*Q) (type: Peaking) gainLinear = 10^(gain/20) a0 = 1 + alpha/A a1 = -2 * cos(w0) a2 = 1 - alpha/A b0 = (1 + alpha*A) * gainLinear b1 = -(2 * cos(w0)) * gainLinear b2 = (1 - alpha*A) * gainLinear */ float A,w0,alpha,norm,gainLine; A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,0.05*gain); w0=2*M_PI*f0/fs; alpha=sinf(w0)/(2.0*q); norm=1.0/(1.0+alpha/A); coeffs[0]=(1.0+alpha*A)*norm; //b0 считается правильно если gain==0 coeffs[1]=-2.0*norm*cosf(w0); //b1 считается правильно если gain==0 coeffs[2]=(1.0-alpha*A)*norm*gainLine; //b2 считается правильно всегда coeffs[3]=2.0*cosf(w0)*norm*gainLine; //-a1 считается правильно если gain==0 coeffs[4]=-1.0*(1.0-alpha/A)*norm*gainLine; //-a2 считается правильно если gain==0 } //***************************************************************************** //***************************************************************************** // 2 Расчет коэффициентов для полочного фильтра НЧ //***************************************************************************** void TonelLowShelf(float f0,float fs,float q,float boost,float gain,float *coeffs) { /* a0 = (A+1) + (A-1)*cos(ω0) + 2*sqrt(A)*alpha a1 = -2*( (A-1) + (A+1)*cos(ω0) ) a2 = (A+1) + (A-1)*cos(ω0) - 2*sqrt(A)*alpha b0 = A*( (A+1) - (A-1)*cos(ω0) + 2*sqrt(A)*alpha ) * gainLinear b1 = 2*A*( (A-1) - (A+1)*cos(ω0) ) * gainLinear b2 = A*( (A+1) - (A-1)*cos(ω0) - 2*sqrt(A)*alpha ) * gainLinear A = 10^(boost/40) w0 = 2*pi*f0/Fs alpha = sin(w0)/2 * sqrt((A + 1/A)*(1/S - 1) + 2) (type: Shelving) gainLinear = 10^(gain/20) */ float A,w0,alpha,norm,gainLine,S; A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,0.05*gain); w0=2.0*M_PI*f0/fs; S=1.0; alpha = (sinf(w0)/2.0) * sqrtf((A + 1.0/A)*(1.0/S - 1.0) + 2.0 ); norm=1.0/((A+1.0) + (A-1.0)*cosf(w0) + 2.0*sqrtf(A)*alpha); coeffs[0]=(A*( (A+1.0) - (A-1.0)*cosf(w0) + 2.0*sqrtf(A)*alpha ) * gainLine)*norm; //b0 coeffs[1]=(2.0*A*( (A-1.0) - (A+1.0)*cosf(w0) ) * gainLine)*norm; //b1 coeffs[2]=(A*( (A+1.0) - (A-1.0)*cosf(w0) - 2.0*sqrtf(A)*alpha ) * gainLine)*norm; //b2 coeffs[3]=(-2.0*( (A-1.0) + (A+1.0)*cosf(w0)))*norm; //-a1 coeffs[4]=((A+1.0) + (A-1.0)*cosf(w0) - 2.0*sqrtf(A)*alpha)*norm; //-a2 } //***************************************************************************** //***************************************************************************** // 3 Расчет коэффициентов для полочного фильтра ВЧ //***************************************************************************** void TonelHightShelf(float f0,float fs,float q,float boost,float gain,float *coeffs) { /* a0 = (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha a1 = 2*( (A-1) - (A+1)*cos(w0) ) a2 = (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha b0 = A*( (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha ) * gainLinear b1 = -2*A*( (A-1) + (A+1)*cos(w0) ) * gainLinear b2 = A*( (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha ) * gainLinear A = 10^(boost/40) w0 = 2*pi*f0/Fs alpha = sin(w0)/2 * sqrt((A + 1/A)*(1/S - 1) + 2) (type: Shelving) gainLinear = 10^(gain/20) */ float A,w0,alpha,norm,gainLine,S; A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,0.05*gain); w0=2*M_PI*f0/fs; S=1; alpha = (sinf(w0)/2.0) * sqrtf((A + 1.0/A)*(1.0/S - 1.0) + 2.0 ); norm=1.0/((A+1.0) + (A-1.0)*cosf(w0) + 2*sqrtf(A)*alpha); //a0 coeffs[0] = A*( (A+1.0) + (A-1.0)*cos(w0) + 2.0*sqrt(A)*alpha ) * gainLine; //b0 coeffs[1] = -2.0*A*( (A-1.0) + (A+1.0)*cos(w0) ) * gainLine; //b1 coeffs[2] = A*( (A+1.0) + (A-1.0)*cos(w0) - 2.0*sqrt(A)*alpha ) * gainLine; //b2 coeffs[3] = 2.0*( (A-1.0) - (A+1.0)*cos(w0) ); //-a1 coeffs[4] = (A+1.0) - (A-1.0)*cos(w0) - 2.0*sqrt(A)*alpha; //-a2 } //***************************************************************************** Изменено 6 сентября, 2019 пользователем smart_pic Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smart_pic 7 7 сентября, 2019 Опубликовано 7 сентября, 2019 · Жалоба На данный момент пока не решен вопрос с расчетом коэффициентов полочного фильтра. Позже выложу программы на С для рассчета коэффициентов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ig_z 0 8 сентября, 2019 Опубликовано 8 сентября, 2019 · Жалоба On 9/6/2019 at 6:11 PM, smart_pic said: Кроме thermit наверное и помочь некому. В полочных фильтрах добавился непонятный параметр S. не знаю для чего он и как считать его. В моих расчетах S влияет на "кривизну" кривой. Красная построена для S~0.9, синяя для S~0.35 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smart_pic 7 8 сентября, 2019 Опубликовано 8 сентября, 2019 · Жалоба Это все верно . В описании на студию про это написано. Я проверяю свои формулы рассчета коэффициентов. Я ввожу F, Q, Boost и получаю 5 коэффициентов для ДСП. Вот формула рассчета альфы, но нигде не написано как считать S. alpha = (sinf(w0)/2.0) * sqrtf((A + 1.0/A)*(1.0/S - 1.0) + 2.0 ); Для других фильтров расчеты совпадают с расчетами сигма студии. В принцепе , когда ДСП будет управляться с ВЕБ интерфейса, то можно на слух подстроить нужную характеристику. Но на данном этапе хочется убедиться в правильности рассчетов, производимых МК. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smart_pic 7 1 января, 2020 Опубликовано 1 января, 2020 · Жалоба Продолжил заниматься расчетом коэффициентов для фильтров ADAU1701/ Как обещал вот программы расчета коэф на Си. //***************************************************************************** //***************************************************************************** #define M_PI 3.14159265358979323846 #include <math.h> //***************************************************************************** // 1 Расчет коэффициентов для полосового фильтра PeakingFiltr //***************************************************************************** void PeakingFiltr(float f0,float fs,float q,float boost,float gain,float *coeffs) { float A,w0,alpha,norm,gainLine; /* alpha = sin(?0)/(2*Q) a0 = 1 + alpha/A b0 = (1 + alpha*A) * gainLinear b1 = -(2 * cos(?0)) * gainLinear b2 = (1 - alpha*A) * gainLinear a1 = -2 * cos(?0) a2 = 1 - alpha/A */ A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,(float)gain/20); w0=2.0*M_PI*f0/fs; alpha=sinf(w0)/2.0/q; norm=1.0/(1.0+(alpha/A)); //a0 coeffs[0]=(1.0+alpha*A)*norm*gainLine; //b0 coeffs[1]=-2.0*norm*cosf(w0)*gainLine; //b1 coeffs[2]=(1.0-alpha*A)*norm*gainLine; //b2 coeffs[3]=2.0*cosf(w0)*norm; //-a1 coeffs[4]=-1.0*(1.0-alpha/A)*norm; //-a2 } //***************************************************************************** //***************************************************************************** // 2 Расчет коэффициентов для полочного фильтра НЧ //***************************************************************************** void TonelLowShelf(float f0,float fs,float q,float boost,float gain,float *coeffs) { /* a0 = (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha a1 = -2*( (A-1) + (A+1)*cos(w0) ) a2 = (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha b0 = A*( (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha ) * gainLinear b1 = 2*A*( (A-1) - (A+1)*cos(w0) ) * gainLinear b2 = A*( (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha ) * gainLinear alpha = sin(w0)/2 * sqrt( (A + 1/A)*(1/S - 1) + 2 ) */ float A,w0,alpha,norm,gainLine,S; A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,0.05*gain); w0=2.0*M_PI*f0/fs; S=1.0; alpha = (sinf(w0)/2.0) * sqrtf((A + 1.0/A)*(1.0/S - 1.0) + 2.0 ); norm=1.0/((A+1.0) + (A-1.0)*cosf(w0) + 2.0*sqrtf(A)*alpha); //a0 coeffs[0]=(A*( (A+1.0) - (A-1.0)*cosf(w0) + 2.0*sqrtf(A)*alpha ) * gainLine)*norm; //b0 coeffs[1]=(2.0*A*( (A-1.0) - (A+1.0)*cosf(w0) ) * gainLine)*norm; //b1 coeffs[2]=(A*( (A+1.0) - (A-1.0)*cosf(w0) - 2.0*sqrtf(A)*alpha ) * gainLine)*norm; //b2 coeffs[3]=(-2.0*( (A-1.0) + (A+1.0)*cosf(w0)))*norm; //-a1 coeffs[4]=((A+1.0) + (A-1.0)*cosf(w0) - 2.0*sqrtf(A)*alpha)*norm; //-a2 } //***************************************************************************** //***************************************************************************** // 3 Расчет коэффициентов для полочного фильтра ВЧ //***************************************************************************** void TonelHightShelf(float f0,float fs,float q,float boost,float gain,float *coeffs) { /* a0 = (A+1) - (A-1)*cos(?0) + 2*sqrt(A)*alpha alpha = sin(?0)/2 * sqrt( (A + 1/A)*(1/S - 1) + 2 ) */ float A,w0,alpha,norm,gainLine,S; A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,0.05*gain); w0=2*M_PI*f0/fs; S=1; alpha = (sinf(w0)/2.0) * sqrtf((A + 1.0/A)*(1.0/S - 1.0) + 2.0 ); norm=1.0/((A+1.0) + (A-1.0)*cosf(w0) + 2*sqrtf(A)*alpha); //a0 coeffs[0] = A*( (A+1.0) + (A-1.0)*cos(w0) + 2.0*sqrt(A)*alpha ) * gainLine; //b0 coeffs[1] = -2.0*A*( (A-1.0) + (A+1.0)*cos(w0) ) * gainLine; //b1 coeffs[2] = A*( (A+1.0) + (A-1.0)*cos(w0) - 2.0*sqrt(A)*alpha ) * gainLine; //b2 coeffs[3] = 2.0*( (A-1.0) - (A+1.0)*cos(w0) ); //-a1 coeffs[4] = (A+1.0) - (A-1.0)*cos(w0) - 2.0*sqrt(A)*alpha; //-a2 } //***************************************************************************** //***************************************************************************** //***************************************************************************** // 4 Расчет коэффициентов для фильтра НЧ //***************************************************************************** void GeneralLowPass(float f0,float fs,float q,float boost,float gain,float *coeffs) { float A,w0,alpha,norm,gainLine; /* alpha = sin(w0)/(2*Q) a0 = 1 + alpha a1 = -2*cos(w0) a2 = 1 - alpha b0 = (1 - cos(w0)) * gainLinear / 2 b1 = 1 - cos(w0) * gainLinear b2 = (1 - cos(w0)) * gainLinear / 2 */ A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,(float)gain/20); w0=2.0*M_PI*f0/fs; alpha=sinf(w0)/2.0/q; norm=1.0/(1.0+alpha); //a0 coeffs[0]=(1.0-cosf(w0))*gainLine/2*norm; //b0 coeffs[1]=(1.0-cosf(w0))*gainLine *norm; //b1 coeffs[2]=(1.0-cosf(w0))*gainLine/2*norm; //b2 coeffs[3]=2.0*cosf(w0)*norm; //-a1 coeffs[4]=-1.0*(1.0-alpha)*norm; //-a2 } //***************************************************************************** //***************************************************************************** //***************************************************************************** // 5 Расчет коэффициентов для фильтра ВЧ //***************************************************************************** void GeneralHightPass(float f0,float fs,float q,float boost,float gain,float *coeffs) { float A,w0,alpha,norm,gainLine; /* alpha = sin(w0)/(2*Q) a0 = 1 + alpha a1 = -2*cos(w0) a2 = 1 - alpha b0 = (1 + cos(w0)) * gainLinear / 2 b1 = -(1 + cos(w0)) * gainLinear b2 = (1 + cos(w0)) * gainLinear / 2 */ A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,0.05*gain); w0=2*M_PI*f0/fs; alpha=sinf(w0)/2.0/q; norm=1.0/(1.0+alpha); coeffs[0]=(1.0+cosf(w0))*gainLine/2*norm; //b0 coeffs[1]=-1.0*(1.0+cosf(w0))*gainLine*norm; //b1 coeffs[2]=(1.0+cosf(w0))*gainLine/2*norm; //b2 coeffs[3]=2.0*cosf(w0)*norm; //-a1 coeffs[4]=-1.0*(1.0-alpha)*norm; //-a2 } //***************************************************************************** //***************************************************************************** //***************************************************************************** // 6 Расчет коэффициентов для фильтра НЧ Butterworth //***************************************************************************** void ButterworthLowPass(float f0,float fs,float q,float boost,float gain,float *coeffs) { /* alpha = sin(w0) / (2.0 * 1/sqrt(2)) a0 = 1 + alpha a1 = -2*cos(w0) a2 = 1 - alpha b0 = (1 - cos(w0)) * gainLinear / 2 b1 = 1 - cos(w0) * gainLinear b2 = (1 - cos(w0)) * gainLinear / 2 */ float A,w0,alpha,norm,gainLine; A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,(float)gain/20); w0=2.0*M_PI*f0/fs; alpha=sinf(w0)/(2.0* 1/sqrtf(2)); norm=1.0/(1.0+alpha); //a0 coeffs[0]=(1.0-cosf(w0))*gainLine/2*norm; //b0 coeffs[1]=(1.0-cosf(w0))*gainLine *norm; //b1 coeffs[2]=(1.0-cosf(w0))*gainLine/2*norm; //b2 coeffs[3]=2.0*cosf(w0)*norm; //-a1 coeffs[4]=-1.0*(1.0-alpha)*norm; //-a2 } //***************************************************************************** //***************************************************************************** //***************************************************************************** // 7 Расчет коэффициентов для фильтра ВЧ Butterworth //***************************************************************************** void ButterworthHightPass(float f0,float fs,float q,float boost,float gain,float *coeffs) { /* a0 = 1 + alpha a1 = -2*cos(w0) a2 = 1 - alpha b0 = -(1 + cos(w0)) * gainLinear / 2 b1 = -(1 + cos(w0)) * gainLinear b2 = -(1 + cos(w0)) * gainLinear / 2 alpha = sin(w0) / (2.0 * 1/sqrt(2)) */ float A,w0,alpha,norm,gainLine; A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,0.05*gain); w0=2*M_PI*f0/fs; alpha=sinf(w0)/(2.0* 1/sqrtf(2)); norm=1.0/(1.0+alpha); coeffs[0]=(1.0+cosf(w0))*gainLine/2*norm; //b0 coeffs[1]=-1.0*(1.0+cosf(w0))*gainLine*norm; //b1 coeffs[2]=(1.0+cosf(w0))*gainLine/2*norm; //b2 coeffs[3]=2.0*cosf(w0)*norm; //-a1 coeffs[4]=-1.0*(1.0-alpha)*norm; //-a2 } //***************************************************************************** //***************************************************************************** //***************************************************************************** // 8 Расчет коэффициентов для фильтра НЧ Bessel //***************************************************************************** void BesselLowPass(float f0,float fs,float q,float boost,float gain,float *coeffs) { float A,w0,alpha,norm,gainLine; A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,(float)gain/20); w0=2.0*M_PI*f0/fs; alpha=sinf(w0)/(2.0* 1/sqrtf(3)); norm=1.0/(1.0+alpha); //a0 coeffs[0]=(1.0-cosf(w0))*gainLine/2*norm; //b0 coeffs[1]=(1.0-cosf(w0))*gainLine *norm; //b1 coeffs[2]=(1.0-cosf(w0))*gainLine/2*norm; //b2 coeffs[3]=2.0*cosf(w0)*norm; //-a1 coeffs[4]=-1.0*(1.0-alpha)*norm; //-a2 } //***************************************************************************** //***************************************************************************** //***************************************************************************** // 9 Расчет коэффициентов для фильтра ВЧ Bessel //***************************************************************************** void BesselHightPass(float f0,float fs,float q,float boost,float gain,float *coeffs) { float A,w0,alpha,norm,gainLine; A=powf(1.0e1,0.025*boost); gainLine=powf(1.0e1,0.05*gain); w0=2*M_PI*f0/fs; alpha=sinf(w0)/(2.0* 1/sqrtf(3)); norm=1.0/(1.0+alpha); coeffs[0]=(1.0+cosf(w0))*gainLine/2*norm; //b0 coeffs[1]=-1.0*(1.0+cosf(w0))*gainLine*norm; //b1 coeffs[2]=(1.0+cosf(w0))*gainLine/2*norm; //b2 coeffs[3]=2.0*cosf(w0)*norm; //-a1 coeffs[4]=-1.0*(1.0-alpha)*norm; //-a2 } //***************************************************************************** //***************************************************************************** Возможно кому пригодится. Остался нерешенным вопрос с полочными фильтрами. Непонятно как Сигма студия считает коэф для данного типа фильтра. Может быть кто то уже это проходил? Прошу откликнуться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 3 января, 2020 Опубликовано 3 января, 2020 · Жалоба Я не стал заморачиваться БИХ фильтрами, неудобные, фазу портят, произвольную АЧХ-ФЧХ не нарисовать. Делаю длинный КИХ фильтр линейнофазовый методом частотного семплирования. По желанию пользователя (меня то бишь) перевожу его в минимально-фазовый известным методом через цепструм. Недостаток - относительно высокая ресурсоемкость, впрочем для эквала на 20 тыщ точек и STM32H7 хватает и еще на экран остается. Полочник рисую как две полки :) и между полками две полупараболы с разным знаком. Мне то все равно, что сэмплировать, АЧХ можно хоть пальцем рисовать (но неудобно, поэтому использую ручки с иммитацией откликов БИХ, за исключением полочников - полочники в БИХ реализации при высокой крутинзне дают выброс, горбик на АЧХ, мне оно не надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smart_pic 7 3 января, 2020 Опубликовано 3 января, 2020 · Жалоба 1 hour ago, DASM said: Я не стал заморачиваться БИХ фильтрами, неудобные, фазу портят, произвольную АЧХ-ФЧХ не нарисовать. Делаю длинный КИХ фильтр линейнофазовый методом частотного семплирования. По желанию пользователя (меня то бишь) перевожу его в минимально-фазовый известным методом через цепструм. Недостаток - относительно высокая ресурсоемкость, впрочем для эквала на 20 тыщ точек и STM32H7 хватает и еще на экран остается. Не понял немного. Обработка идет на STM32H7 ? Я на ADAU1701 делаю , а управление на PIC32 через ВЕБ. Вот видео снял небольшое www.yakorev.com.ru/dspcontr.avi Управление громкостью и индикацию уровня сделал, теперь хочу управление фильтрами прикрутить. Расчет коэф осилил, остается ВЕБ прикрутить Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 3 января, 2020 Опубликовано 3 января, 2020 · Жалоба 2 hours ago, smart_pic said: Не понял немного. Обработка идет на STM32H7 ? Я на ADAU1701 делаю , а управление на PIC32 через ВЕБ. Вот видео снял небольшое www.yakorev.com.ru/dspcontr.avi Управление громкостью и индикацию уровня сделал, теперь хочу управление фильтрами прикрутить. Расчет коэф осилил, остается ВЕБ прикрутить Да, на Н7 все и считал Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться