Перейти к содержанию
    

DSP ADAU1701 расчет коэффициентов фильтров

Продолжаю заниматься фильтрами для ДСП 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
}
//*****************************************************************************
	

 

Изменено пользователем smart_pic

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На данный момент пока не решен вопрос с расчетом коэффициентов полочного фильтра. Позже выложу программы на С для рассчета коэффициентов.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 9/6/2019 at 6:11 PM, smart_pic said:

 

Кроме  thermit    наверное и помочь некому.

В полочных фильтрах добавился непонятный параметр S. не знаю для чего он и как считать его.

 

В моих расчетах S влияет на "кривизну" кривой. Красная построена для S~0.9, синяя для S~0.35 

 

image.thumb.png.b1a22e0e980dd65462bb1792c88ca29c.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это все верно . В описании на студию про это написано. Я проверяю свои формулы рассчета коэффициентов.

Я ввожу F, Q, Boost и получаю 5 коэффициентов для ДСП.

Вот формула рассчета альфы, но нигде не написано как  считать S.

    alpha = (sinf(w0)/2.0) * sqrtf((A + 1.0/A)*(1.0/S - 1.0) + 2.0 );

Для других фильтров расчеты совпадают с расчетами сигма студии.

В принцепе , когда ДСП будет управляться с ВЕБ интерфейса, то можно на слух подстроить нужную характеристику. Но на данном этапе хочется убедиться в правильности рассчетов, производимых МК.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Продолжил заниматься расчетом коэффициентов для фильтров 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
}
//*****************************************************************************
//*****************************************************************************

Возможно кому пригодится.

Остался нерешенным вопрос с полочными фильтрами.

Непонятно как Сигма студия считает коэф для данного типа фильтра.

Может быть кто то уже это проходил?

Прошу откликнуться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не стал заморачиваться БИХ фильтрами, неудобные, фазу портят, произвольную АЧХ-ФЧХ не нарисовать. Делаю длинный КИХ фильтр линейнофазовый методом частотного семплирования. По желанию пользователя (меня то бишь) перевожу его в минимально-фазовый известным методом через цепструм. Недостаток - относительно высокая ресурсоемкость, впрочем для эквала на 20 тыщ точек и STM32H7 хватает и еще на экран остается.

Полочник рисую  как две полки :) и между полками две полупараболы с разным знаком. 

Мне то все равно, что сэмплировать, АЧХ можно хоть пальцем рисовать (но неудобно, поэтому использую ручки с иммитацией откликов БИХ, за исключением полочников - полочники в БИХ реализации при высокой крутинзне дают выброс, горбик на АЧХ, мне оно не надо.

442405763_.thumb.png.4796ce75787c30c7f7d66891f402ddef.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, DASM said:

Я не стал заморачиваться БИХ фильтрами, неудобные, фазу портят, произвольную АЧХ-ФЧХ не нарисовать. Делаю длинный КИХ фильтр линейнофазовый методом частотного семплирования. По желанию пользователя (меня то бишь) перевожу его в минимально-фазовый известным методом через цепструм. Недостаток - относительно высокая ресурсоемкость, впрочем для эквала на 20 тыщ точек и STM32H7 хватает и еще на экран остается.

 

Не понял немного. Обработка идет на STM32H7 ?

Я на ADAU1701 делаю , а управление на PIC32 через ВЕБ.

Вот видео снял небольшое www.yakorev.com.ru/dspcontr.avi

Управление громкостью и индикацию уровня сделал, теперь хочу управление фильтрами прикрутить. Расчет коэф осилил, остается ВЕБ прикрутить

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, smart_pic said:

Не понял немного. Обработка идет на STM32H7 ?

Я на ADAU1701 делаю , а управление на PIC32 через ВЕБ.

Вот видео снял небольшое www.yakorev.com.ru/dspcontr.avi

Управление громкостью и индикацию уровня сделал, теперь хочу управление фильтрами прикрутить. Расчет коэф осилил, остается ВЕБ прикрутить

 

 

Да, на Н7 все и считал

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...