在频率域进行音频滤波(Python)

最近一个项目需要对声音文件进行一个滤波处理,由于并没有这种经验,所以借助图像的滤波来实现一下

  1. 首先导入需要的包和设置路径
import wave as we
import numpy as np
import matplotlib.pyplot as plt

dir = r'路径'
  1. 现在写读入音频和傅里叶变换的函数,载入数据,查看现在的状态
def read_wav(wavfile, plots=True, normal=False):
    f = wavfile
    params = f.getparams()
    # print(params)
    nchannels, sampwidth, framerate, nframes = params[:4]
    strData = f.readframes(nframes)  # 读取音频,字符串格式
    waveData = np.frombuffer(strData, dtype=np.int16)  # 将字符串转化为int
    # wave幅值归一化
    if normal == True:
        waveData = waveData*1.0/(max(abs(waveData)))
    # 绘图
    if plots == True:
        time = np.arange(0, nframes)*(1.0 / framerate)
        plt.figure(dpi=100)
        plt.plot(time, waveData)
        plt.xlabel("Time")
        plt.ylabel("Amplitude")
        plt.title("Single channel wavedata")
        plt.show()
    return (waveData, time)

def fft_wav(waveData, plots=True):
    f_array = np.fft.fft(waveData)  # 傅里叶变换,结果为复数数组
    f_abs = f_array
    axis_f = np.linspace(0, 250, np.int(len(f_array)/2))  # 映射到250
    # axis_f = np.linspace(0, 250, np.int(len(f_array)))  # 映射到250
    if plots == True:
        plt.figure(dpi=100)
        plt.plot(axis_f, np.abs(f_abs[0:len(axis_f)]))
        # plt.plot(axis_f, np.abs(f_abs))
        plt.xlabel("Frequency")
        plt.ylabel("Amplitude spectrum")
        plt.title("Tile map")
        plt.show()
    return f_abs

调用绘制声波图

f = we.open(dir+r'\test.wav', 'rb')
waveData, time = read_wav(f)

在这里插入图片描述
绘制傅里叶变换的图像

wavefft = fft_wav(waveData)

在这里插入图片描述

  1. 现在把后面的不需要的磨平
# 截取
step_hz = 250 / (len(waveData) / 2)
tab_hz = 20
savewav = []
for i in range(int(tab_hz/step_hz)):
    savewav.append(wavefft[i])
for j in range(int(tab_hz/step_hz), (len(wavefft) - int(tab_hz/step_hz))):
    savewav.append(0)  
for i in range((len(wavefft) - int(tab_hz/step_hz)), len(wavefft)):
    savewav.append(wavefft[i])
# 绘图
axis_f = np.linspace(0, 250, np.int(len(wavefft)/2))  # 映射到250
# axis_f = np.linspace(0, 250, np.int(len(wavefft)))  # 映射到250
plt.figure(dpi=100)
plt.plot(axis_f, np.abs(savewav[0:len(axis_f)]))
# plt.plot(axis_f, np.abs(savewav))
plt.xlabel("Frequency")
plt.ylabel("Amplitude spectrum")
plt.title("Tile map after wave filtering")
plt.show()

在这里插入图片描述
绘制变换后的声波图

# 傅里叶逆变换
i_array = np.fft.ifft(savewav)
# 绘图
plt.figure(dpi=100)
plt.plot(time, i_array.real)
plt.xlabel("Time")
plt.ylabel("Amplitude")
plt.title("Single channel wavedata after wave filtering")
plt.show()

在这里插入图片描述

  1. 保存声音文件
# 保存
save_wav = i_array.real.reshape((len(i_array), 1)).T.astype(np.short)
# print(save_wav.shape)
# i_array.real.tofile(dir+r'\test.bin')

f = we.open(dir+r'\test_wf.wav', "wb")
# 配置声道数、量化位数和取样频率
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(16000)
# 将wav_data转换为二进制数据写入文件
f.writeframes(save_wav.tostring())
f.close()
  • 10
    点赞
  • 87
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值