FIR 带通滤波器参数设计流程

FIR 带通滤波器参数设计流程假设有一段10kHz的语言,现需要对2~3kHz之间的语言信号进行提取,要求1.5kHz及3.5kHz以上的频率需要有40dB的衰减1、求数字频率指标通带下边频:wpl=2∗π∗fpl/fs=0.4πw_{pl}=2*\pi*f_{pl}/f_s=0.4\piwpl​=2∗π∗fpl​/fs​=0.4π通带上边频:wph=2∗π∗fph/fs=0.6πw_{ph}=2*\pi*f_{ph}/f_s=0.6\piwph​=2∗π∗fph​/fs​=0.6π下阻带上变频:wsl=2∗π∗fsl

大家好,又见面了,我是你们的朋友全栈君。

假设有一段10kHz的语言,现需要对2~3kHz之间的语言信号进行提取,要求1.5kHz及3.5kHz以上的频率需要有40dB的衰减

1、求数字频率指标

通带下边频:
w p l = 2 ∗ π ∗ f p l / f s = 0.4 π w_{pl}=2*\pi *f_{pl}/f_s=0.4\pi wpl=2πfpl/fs=0.4π
通带上边频:
w p h = 2 ∗ π ∗ f p h / f s = 0.6 π w_{ph}=2*\pi *f_{ph}/f_s=0.6\pi wph=2πfph/fs=0.6π
下阻带上变频:
w s l = 2 ∗ π ∗ f s l / f s = 0.3 π w_{sl}=2*\pi *f_{sl}/f_s=0.3\pi wsl=2πfsl/fs=0.3π
上阻带下变频:
w s h = 2 ∗ π ∗ f s h / f s = 0.7 π w_{sh}=2*\pi *f_{sh}/f_s=0.7\pi wsh=2πfsh/fs=0.7π

2、选取窗函数

在这里插入图片描述

根据阻带衰减查表,可选汉宁窗,过度带宽 Δ w = w p l − w s l = 0.1 π \Delta_w=w_{pl}-w_{sl}=0.1\pi Δw=wplwsl=0.1π
由汉宁窗过度带宽确定阶数N
N = 6.2 π / Δ w = 62 N=6.2\pi/\Delta_w=62 N=6.2π/Δw=62
取N为奇数N=63
a = ( N − 1 ) / 2 a = (N-1)/2 a=(N1)/2
因此窗函数:
w ( n ) = 1 2 [ 1 − c o s ( 2 π n a ) ] w(n)=\frac{1}{2}[1-cos(\frac{2\pi n}{a})] w(n)=21[1cos(a2πn)]

3、求理想带通滤波器的单位脉冲响应

理想带通滤波器的截止频率:
w c l = ( w p l + w s l ) / 2 w_{cl}=(w_{pl}+w_{sl})/2 wcl=(wpl+wsl)/2
w c h = ( w p h + w s h ) / 2 w_{ch}=(w_{ph}+w_{sh})/2 wch=(wph+wsh)/2
理想带通滤波器的单位脉冲响应:

h d ( n ) = s i n [ w c h ∗ ( n − a ) ] − s i n [ w c l ∗ ( n − a ) ] π ∗ ( n − a ) h_d(n)=\frac{sin[w_{ch}*(n-a)]-sin[w_{cl}*(n-a)]}{\pi*(n-a)} hd(n)=π(na)sin[wch(na)]sin[wcl(na)]

4、求FIR滤波参数

h ( n ) = h d ( n ) w ( n ) h(n)=h_d(n)w(n) h(n)=hd(n)w(n)

5、算法仿真

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from scipy.fftpack import fft,ifft
from decimal import Decimal
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['font.family']='sans-serif'

 
class filter:
    def __init__(self,h):
        self.order=len(h)
        self.h=h
        self.output=[]
    def FIR_Filter(self,vi):
        for i in range(len(vi)):
            sum=0
            if i < self.order:
                for j in range(i):
                    sum=sum + self.h[j]*vi[i-j]
            else:      
                for j in range(self.order):
                    sum=sum + self.h[j]*vi[i-j]
                
            self.output.append(sum)   
        return self.output
        
       

#采样为10Khz
#1.5khz以下及3.5khz以上至少40db的衰减

f_sl = 1500
f_sh = 3500
f_pl = 2000
f_ph = 3000
f_s  = 10000
#通带下边频
W_pl = 2*np.pi*f_pl/f_s

W_ph = 2*np.pi*f_ph/f_s

W_sl = 2*np.pi*f_sl/f_s
W_sh = 2*np.pi*f_sh/f_s

W_D = W_pl - W_sl

N = 6.2*np.pi/(W_D)
if N%2==0:
    N=N+1
print(N)
a = (N-1)/2
n=np.linspace(0,N-1,N)

R_n =  1
#汉宁窗口函数
w_n = 0.5*(1-np.cos(2*np.pi*n/(N-1)))

W_cl = (W_pl+W_sl)/2
W_ch = (W_ph+W_sh)/2
#用一个靠近a的小数将a值替换掉,避免出现除0的情况
a=30.9999999999
h_d  = (np.sin(W_ch*(n-a))-np.sin(W_cl*(n-a)))/(2*np.pi*(n-a))
h_c = h_d*w_n

numtaps=63

array= h_c
plt.figure(1)
yy_1=fft(array)                     #快速傅里叶变换
yf_1=abs(fft(array))                # 取模
yf1_1=abs(fft(array))/((len(array)/2))           #归一化处理
yf2_1 = yf1_1[range(int(len(array)/2))]  #由于对称性,只取一半区间
#plt.plot(h_d,'b')
plt.subplot(221)
plt.title('滤波系数')  # 定义标题
plt.plot(array,'g')
plt.plot(h_c,'K')
plt.subplot(222)
plt.title('滤波系数FFT')  # 定义标题
plt.plot(yf2_1,'r')
plt.show()

x=np.linspace(0,1,f_s)
signal_array = np.sin(2*np.pi*2000*x)
for i in range(10):
    if 1000*i != 2000:
        signal_array+=np.sin(2*np.pi*1000*x*i)#+np.sin(2*np.pi*175*x)+np.sin(2*np.pi*350*x)+np.sin(2*np.pi*500*x)
plt.figure(2)        
Weight = array
FIR_filter=filter(Weight)
output = FIR_filter.FIR_Filter(signal_array)   
y=  signal_array
xf = np.arange(len(y)) 
yy=fft(y)                     #快速傅里叶变换
yf=abs(fft(y))                # 取模
yf1=abs(fft(y))/((len(x)/2))           #归一化处理
yf2 = yf1[range(int(len(x)/2))]  #由于对称性,只取一半区间
plt.subplot(221)
plt.title('原始信号')  # 定义标题
plt.plot(xf,signal_array,'b') #显示原始信号的FFT模值

plt.subplot(222)
plt.title('原始信号FFT')  # 定义标题
plt.plot(xf,yf1,'r') #显示原始信号的FFT模值

yy_1=fft(output)                     #快速傅里叶变换
yf_1=abs(fft(output))                # 取模
yf1_1=abs(fft(output))/((len(x)/2))           #归一化处理
yf2_1 = yf1_1[range(int(len(x)/2))]  #由于对称性,只取一半区间
plt.subplot(223)
plt.title('滤波后的信号')  # 定义标题
plt.plot(xf,output,'b') 
plt.subplot(224)
plt.title('滤波后的信号FFT')  # 定义标题
plt.plot(xf,yf1_1,'r') #显示原始信号的FFT模值

        

6、算法结果

在这里插入图片描述

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/138893.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Spring AOP IOC 实现原理,面试问到如何回答[通俗易懂]

    Spring AOP IOC 实现原理,面试问到如何回答[通俗易懂]IOC:控制反转也叫依赖注入,IOC利用java反射机制,AOP利用代理模式。所谓控制反转是指,本来被调用者的实例是由调用者来创建的,这样的缺点是耦合性太强,IOC则是统一交给spring来管理创建,将对象交给容器管理,你只需要在spring配置文件总配置相应的bean,以及设置相关的属性,让spring容器来生成类的实例对象以及管理对象。在spring容器启动的时候,spring会把你在配置文件…

    2022年6月28日
    151
  • 如何使用Journalctl查看并操作Systemd日志

    如何使用Journalctl查看并操作Systemd日志提供:ZStack云计算内容简介作为最具吸引力的优势,systemd拥有强大的处理与系统日志记录功能。在使用其它工具时,日志往往被分散在整套系统当中,由不同的守护进程及进程负责处理,这意味着我们很难跨越多种应用程序对其内容进行解读。相比之下,systemd尝试提供一套集中化管理方案,从而统一打理全部内核及用户级进程的日志信息。这套系统能够收集并管理日志内容,而这也就是我们所熟知的journal。J

    2022年5月23日
    49
  • Ubuntu 20.04 搭建OpenStack Yoga(allinone)

    Ubuntu 20.04 搭建OpenStack Yoga(allinone)文章目录环境准备换源网络配置静态IP桥接永久修改DNS主机名基础服务数据库etcdmemcachedOpenStackNova很多文章都是devstack安装的allinone,我这里使用源码组件手动安装。环境准备这里需要先配置一些环境。首先我这里是虚拟机安装的系统,可能设置的密码不是当前用户的root密码,反正就得重置一下执行下面的命令,然后输入安装系统设置的密码,之后就可以了。sudopasswdroot换源需要先换一个源,方便下载换阿里源gedit/etc/apt/sourc

    2022年10月29日
    0
  • 深度学习笔记(七)–ResNet(残差网络)

    深度学习笔记(七)–ResNet(残差网络)内容来自吴恩达老师视频,网易云课堂有哦ResNets非常非常深的神经网络是很难训练的,因为存在梯度消失和梯度爆炸问题。ResNets是由残差块(Residualblock)构建的,首先解释一下什么是残差块。这是一个两层神经网络,在层进行激活,得到,再次进行激活,两层之后得到。计算过程是从开始,首先进行线性激活,根据这个公式:,通过算出,即乘以权重矩阵,再加上偏差因…

    2022年6月25日
    26
  • 用PHP,怎么获取PHP.ini中的文件上传最大的字节数。也就是默认的2M

    用PHP,怎么获取PHP.ini中的文件上传最大的字节数。也就是默认的2M

    2021年9月20日
    54
  • VCProtect虚拟机加壳工具

    VCProtect虚拟机加壳工具虚拟机加壳工具,可以给目标程序加上虚拟机,同时提供多态变形功能。下载http://www.vcprotect.com

    2022年6月27日
    47

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号