📄 firfilter.java
字号:
package FIRFilterDesign;
class FIRFilter {
public static final int LP = 1;
public static final int HP = 2;
public static final int BP = 3;
public static final int RECTANGULAR = 4;
public static final int HANNING = 5;
public static final int HAMMING = 6;
public static final int BLACKMAN = 7;
int order;
int windowType, filterType, freqPoints;
float f1, f2, fN;
float[] a;
public void FIRFilter() {
// initial settings
windowType = RECTANGULAR;
filterType = LP;
order = 1;
// following settings based on default 8000 samples/s rate:
fN = 4000.0f;
f1 = 0.0f;
f2 = 1000.0f;
}
public void setWindowType(String wt) {
if (wt.equals("矩形窗")) windowType = RECTANGULAR;
if (wt.equals("汉宁窗")) windowType = HANNING;
if (wt.equals("哈明窗")) windowType = HAMMING;
if (wt.equals("布拉克曼窗")) windowType = BLACKMAN;
}
public void setWindowType(int wt) {
windowType = wt;
}
public void setFilterType(String ft) {
if (ft.equals("低通")) filterType = LP;
if (ft.equals("带通")) filterType = BP;
if (ft.equals("高通")) filterType = HP;
}
public void setFilterType(int ft) {
filterType = ft;
}
public void setOrder(int n) {
order = n;
}
public void setRate(float rate) {
fN = 0.5f * rate;
}
public void setFreq1(float f1) {
this.f1 = f1;
}
public void setFreq2(float f2) {
this.f2 = f2;
}
public void setFreqPoints(int fp) {
freqPoints = fp;
}
public float getCoeff(int i) {
// returns FIR filter coefficient with index i
return a[i];
}
//阻带最小衰减
public float atten() {
switch (windowType) {
case RECTANGULAR: return 21.0f;
case HANNING: return 44.0f;
case HAMMING: return 53.0f;
case BLACKMAN: return 74.0f;
default: return 999.0f;
}
}
//精确过渡带宽
public float trBand() {
switch (windowType) {
case RECTANGULAR: return 1.84f*fN/order;
case HANNING: return 6.22f*fN/order;
case HAMMING: return 6.64f*fN/order;
case BLACKMAN: return 11.13f*fN/order;
default: return 999.0f;
}
}
public void design() {
// window function values
int m = order / 2;
float[] win = new float[m+1];
float r;
switch (windowType) {
case RECTANGULAR:
for (int n=1; n <= m; n++)
win[n] = 1.0f;
break;
case HANNING:
r = (float)Math.PI/(m+1);
for (int n=1; n <= m; n++)
win[n] = 0.5f + 0.5f*(float)Math.cos(n*r);
break;
case HAMMING:
r = (float)Math.PI/m;
for (int n=1; n <= m; n++)
win[n] = 0.54f + 0.46f*(float)Math.cos(n*r);
break;
case BLACKMAN:
r = (float)Math.PI/m;
for (int n=1; n <= m; n++)
win[n] = 0.42f + 0.5f*(float)Math.cos(n*r) + 0.08f*(float)Math.cos(2*n*r);
break;
default: for (int n=1; n <= m; n++) win[n] = 1.0f;
}
float w0 = 0.0f;
float w1 = 0.0f;
switch (filterType) {
case LP: w0 = 0.0f;
w1 = (float)Math.PI*(f2 + 0.5f*trBand())/fN;
break;
case HP: w0 = (float)Math.PI;
w1 = (float)Math.PI*(1.0f - (f1 - 0.5f*trBand())/fN);
break;
case BP: w0 = 0.5f * (float)Math.PI * (f1 + f2) / fN;
w1 = 0.5f * (float)Math.PI * (f2 - f1 + trBand()) / fN;
break;
}
// filter coefficients (NB not normalised to unit maximum gain)
a = new float[order+1];
a[0] = w1 / (float)Math.PI;
for (int n=1; n <= m; n++)
a[n] = (float)Math.sin(n*w1)*(float)Math.cos(n*w0)*win[n]/(n*(float)Math.PI);
// shift impulse response to make filter causal:
for (int n=m+1; n<=order; n++) a[n] = a[n - m];
for (int n=0; n<=m-1; n++) a[n] = a[order - n];
a[m] = w1 / (float)Math.PI;
}
public float[] filterGain() {
// filter gain at uniform frequency intervals
float[] g = new float[freqPoints+1];
float theta, s, c, sac, sas;
float gMax = -100.0f;
float sc = 10.0f/(float)Math.log(10.0f);
float t = (float)Math.PI / freqPoints;
for (int i=0; i<=freqPoints; i++) {
theta = i*t;
sac = 0.0f;
sas = 0.0f;
for (int k=0; k<=order; k++) {
c = (float)Math.cos(k*theta);
s = (float)Math.sin(k*theta);
sac += c*a[k];
sas += s*a[k];
}
g[i] = sc*(float)Math.log(sac*sac + sas*sas);
gMax = Math.max(gMax, g[i]);
}
// normalise to 0 dB maximum gain
for (int i=0; i<=freqPoints; i++) g[i] -= gMax;
// normalise coefficients
float normFactor = (float)Math.pow(10.0, -0.05*gMax);
for (int i=0; i<=order; i++) a[i] *= normFactor;
return g;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -