新人求助,C语言转C#
typedef struct {
float slope; //斜率 Shelf:Slope Ovt
float f0; //频率 单位 Hz
float Q; //Q值
float boost; //增益 单位 dB
float gain; //全频带增益 dB
float w0; //= 2*pi*f0/Fs
float boostLinear; //= 10^(boost/40)
float gainLinear; //p->boostLinearv = 10^(gain/20);
float alpha; //
float a0,b0,b1,b2,a1,a2;
uint32_t B0,B1,B2,A1,A2;
} filters;
#define pi M_PI
#define ln(n) M_LN2
const double fs = 48000.0; //DSP的取样频率 48KHz
filters filter; //定义一个滤波
//公共变量计算
void Common_Variables(filters *p)
{
p->boostLinear = pow(10, p->boost/40);
p->w0 = 2*pi*p->f0/fs;
p->gainLinear = pow(10, p->gain /20);
}
//
void coefficients(filters *p)
{
//DSP 内部需要把a0格式化为1.0,所以都要除以a0
p->a1 = 1 * p->a1 / p->a0;
p->a2 = 1 * p->a2 / p->a0;
p->b0 = p->b0 / p->a0;
p->b1 = p->b1 / p->a0;
p->b2 = p->b2 / p->a0;
p->a0 = 1.0;
}
void Low_Shelf(filters *p)
{
Common_Variables(p);
p->alpha = sin(p->w0)/2 * sqrt((p->boostLinear + 1/p->boostLinear)*(1/p->slope - 1) + 2); //(A=boostLinear, S=slope, type: Shelving)
p->a0 = (p->boostLinear+1) + (p->boostLinear-1)*cos(p->w0) + 2*sqrt(p->boostLinear)*p->alpha;
p->a1 = -2* ((p->boostLinear-1) + (p->boostLinear+1)*cos(p->w0));
p->a2 = (p->boostLinear+1) + (p->boostLinear-1)*cos(p->w0) - 2*sqrt(p->boostLinear)*p->alpha;
p->b0 = p->boostLinear*( (p->boostLinear+1) - (p->boostLinear-1)*cos(p->w0) + 2*sqrt(p->boostLinear)*p->alpha ) * p->gainLinear;
p->b1 = 2*p->boostLinear*( (p->boostLinear-1) - (p->boostLinear+1)*cos(p->w0)) * p->gainLinear;
p->b2 = p->boostLinear*( (p->boostLinear+1) - (p->boostLinear-1)*cos(p->w0) - 2*sqrt(p->boostLinear)*p->alpha ) * p->gainLinear;
coefficients(p);
}
void High_Shelf(filters *p)
{
Common_Variables(p);
p->alpha = sin(p->w0)/2 * sqrt((p->boostLinear + 1/p->boostLinear)*(1/p->slope - 1) + 2); //(A=boostLinear, S=slope, type: Shelving)
p->a0 = (p->boostLinear+1) - (p->boostLinear-1)*cos(p->w0) + 2*sqrt(p->boostLinear)*p->alpha;
p->a1 = 2* ( (p->boostLinear-1) - (p->boostLinear+1)*cos(p->w0) );
p->a2 = (p->boostLinear+1) - (p->boostLinear-1)*cos(p->w0) - 2*sqrt(p->boostLinear)*p->alpha;
p->b0 = p->boostLinear*( (p->boostLinear+1) + (p->boostLinear-1)*cos(p->w0) + 2*sqrt(p->boostLinear)*p->alpha ) * p->gainLinear;
p->b1 = -2*p->boostLinear*( (p->boostLinear-1) + (p->boostLinear+1)*cos(p->w0) ) * p->gainLinear;
p->b2 = p->boostLinear*( (p->boostLinear+1) + (p->boostLinear-1)*cos(p->w0) - 2*sqrt(p->boostLinear)*p->alpha ) * p->gainLinear;
coefficients(p);
}
/**
* 计算数字滤波器的频率响应
* num 是数字滤波器的分子多项式系数
* den 是数字滤波器的分母多项式系数
* num_order 是分子多项式的阶数
* den_order 是分母多项式的阶数
* sign = 0 时,x_out 为频率响应的实部, y_out 为频率响应的虚部
* sign = 1 时,x_out 为频率响应的模, y_out 为频率响应的幅角
* sign = 2 时,x_out 为以 dB 为单位的频率响应, y_out 为频率响应的幅角
* len 为,频率响应的取样点数
*/
void gain(double num[], double den[], int num_order, int den_order,
double x_out[], double y_out[], int len, int sign)
{
int i, k;
double zr, zi;
double re, im;
double ar, ai, br, bi;
double numr, numi;
double de, temp;
double freq;
for(k = 0; k < len; k++)
{
// freq = 0.5 * k / (len - 1);
freq = pow(10.0,1.0+k/20.0)/48000.0; //得到一个有对数关系的频率轴,具体的频率请查看excel
zr = cos(-2.0 * M_PI * freq);
zi = sin(-2.0 * M_PI * freq);
br = 0.0;
bi = 0.0;
for(i = num_order; i > 0; i--)
{
re = br;
im = bi;
br = (re + num[i]) * zr - im * zi;
bi = (re + num[i]) * zi + im * zr;
}
ar = 0.0;
ai = 0.0;
for(i = den_order; i > 0; i--)
{
re = ar;
im = ai;
ar = (re + den[i]) * zr - im * zi;
ai = (re + den[i]) * zi + im * zr;
}
br = br + num[0];
ar = ar + 1.0;
numr = ar * br + ai * bi;
numi = ar * bi - ai * br;
de = ar * ar + ai * ai;
x_out[k] = numr / de;
y_out[k] = numi / de;
switch(sign)
{
case 1:
temp = hypot(x_out[k], y_out[k]);
y_out[k] = atan2(y_out[k], x_out[k]);
x_out[k] = temp;
break;
case 2:
temp = x_out[k] * x_out[k] + y_out[k] * y_out[k];
y_out[k] = atan2(y_out[k], x_out[k]);
x_out[k] = 10 *log10(temp);
break;
default:
break;
}
}
}
#define N 68
double den[3];
double num[3];
double x_out[N], y_out[N];
int main(void)
{
while (1)
{
filters *pfilter;
pfilter = &filter;
pfilter->f0 = 1000; //滤波器频率
pfilter->slope = 1.0; //滤波器斜率
pfilter->boost = 3; //增益
pfilter->gain = 0; //全频带增益 以后用到的滤波器此参数都为0,和它有关的参数都可以优化掉
High_Shelf(pfilter); //计算滤波器系数(a0 a1 a2 b0 b1 b2)
num[0] = pfilter->b0;
num[1] = pfilter->b1;
num[2] = pfilter->b2;
den[0] = pfilter->a0;
den[1] = pfilter->a1;
den[2] = pfilter->a2;
// num[0] = 1.390166878700;
// num[1] = -2.544721961021;
// num[2] = 1.173018097878;
// den[0] = 1.0;
// den[1] = -1.798829078674;
// den[2] = 0.817292094231;
_NOP();
gain(num, den, 2, 2, x_out, y_out, N, 2);
for(i = 0; i < N; i ++)
{
f = 0.5 * i / (N - 1);
printf("%f, %f, %f\n", f, x_out[i], y_out[i]);
}
_NOP();
}
}