• 【基于pyAudioKits的Python音频信号处理项目(一)】实现音频频谱分析仪并进行交互式滤波器设计


    pyAudioKits是基于librosa和其他库的强大Python音频工作流支持。

    API速查手册

    通过pip安装:

    pip install pyAudioKits
    
    • 1

    pyAudioKits的GitHub地址,如果这个项目帮助到了你,请为它点上一颗star,谢谢你的支持!如果你在使用过程中有任何问题,请在评论区留言或在GitHub上提issue,我将持续对该项目进行维护。

    在进行音频信号有关研究时,我们常常需要用到语谱图的分析。同时,我们也需要进行降噪或者有用的频率成分的提取。

    常规情况下,为了实现降噪或者有用的频率成分的提取,我们会将整个音频信号通过一个时不变滤波器。如果噪声是平稳信号,该方法可以有效滤除噪声。然而实际情况下,噪声往往是非平稳的,这就意味着我们需要在不同时间点上使用参数不同的滤波器,即使用一个时变滤波器

    短时傅里叶变换可以用于生成音频信号的语谱图,语谱图上包含了信号随时间变化的频率成分信息,因此我们完全可以将时变滤波器的设置和语谱图的分析进行结合

    Filter-Artist基于pyAudioKits开发,实现了一个STFT语谱图定位滤波分析系统,这个系统旨在对音频信号进行短时傅里叶变换。而且,为了更好地对语谱图进行分析,我们让用户可以借助GUI,使用鼠标,在特定时间的特定频点设置巴特沃斯滤波器,交互性地提取自己感兴趣的信号成分、屏蔽噪声,观察滤波后的波形并实时播放滤波后的音频。

    该项目的GitHub地址。如果它对你有用,请为它点上一颗star,谢谢!

    运行环境:

    Python ≥ 3.8.3

    依赖:

    pyAudioKits ≥ 1.0.6

    PyQt5 ≥ 5.15.4

    numpy ≥ 1.22.4

    opencv-python ≥ 4.5.2.52

    1. 在命令行输入:

      python main.py
      
      • 1

      以执行main.py,得到窗口如下图所示。

      请添加图片描述

    2. 点按Load按钮,并读取预置的录音文件rec2_01.wav。

      请添加图片描述

      此时显示了rec2_01.wav的语谱图。

      请添加图片描述

    3. 可以选用多种窗型来显示语谱图。默认展示的是矩形窗的结果:

      请添加图片描述

      使用汉明窗:

      image-20220731054631722
    4. 可以设置巴特沃斯滤波器的阶数和通带/阻带宽度。

      image-20220731054631722
    5. 不勾选Erase Mode的情况下,设置的是带通滤波器。在语谱图上点按鼠标并拖动,则鼠标初始位置决定滤波器设置的起始时间和中心频率,鼠标释放位置决定滤波器设置的结束时间。设置一个宽度较大的高频通带以提取蜂鸣器音。

      image-20220731054631722
    6. 勾选Erase Mode的情况下,设置的是带阻滤波器。在语谱图上点按鼠标并拖动,则鼠标初始位置决定滤波器设置的起始时间和中心频率,鼠标释放位置决定滤波器设置的结束时间。设置三个宽度较小的阻带以消除蜂鸣器音。

      请添加图片描述

    7. 点击play按钮播放音频。

      请添加图片描述

    8. 点击Save按钮对音频进行保存。

      请添加图片描述

    9. 点击Redo按钮重置对音频的编辑。

      请添加图片描述

    核心代码:

    核心代码位于audio.py文件内

    from pyAudioKits.audio import read_Audio
    from pyAudioKits.analyse import FFT
    from pyAudioKits.filters import lowPassButterN, highPassButterN, bandPassButterN, bandStopButterN
    import matplotlib.pyplot as plt
    import numpy as np
    
    class myspectrogram:
        def __init__(self,direction,window):
            self.__wav = read_Audio(direction)	#利用pyAudioKits的api读取音频
            self.__M=0.03	#设置窗长为0.03s
            self.__R=0.015	#设置步长为0.015s
    
            if window=="Hamming":
                self.__Window = "hamming"
            elif window=="Rectangle":
                self.__Window = None
    
        def __stft(self):
            self.__freq = FFT(self.__wav.framing(self.__M, 1 - self.__R/self.__M, self.__Window))	#利用pyAudioKits的api进行短时傅里叶变换
        
        def save(self,direction):
            self.__wav.save(direction)	#利用pyAudioKits的api保存音频
        
        def play(self):
            self.__wav.sound()	#利用pyAudioKits的api播放音频
    
        def drawFreq(self):
            self.__stft()
            #创建子图,并取消横纵坐标
            plt.figure(figsize=(8,2))
            plt.axis('off')
            plt.gca().xaxis.set_major_locator(plt.NullLocator())
            plt.gca().yaxis.set_major_locator(plt.NullLocator())
            plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, hspace = 0, wspace = 0)
            plt.margins(0,0)
            self.__freq.plot(ax=plt.gca(),cbar=False,freq_scale="mel",plot_type="dB")	#将子图传入pyAudioKits的频谱绘制api
            plt.savefig("tmp.png")	#保存子图,后续通过PyQt读取并显示
    
        def filtering(self,n,sizeFreq,erase,xposeStart,yposeStart,xposeEnd,yposeEnd):
            def freq_transform(freq):	#将鼠标在频谱上点击的y轴位置,即一个[0,1]之间的数,映射到梅尔尺度频率
                sr = self.__wav.sr
                length = int(self.__M  * sr / 2)
                max_freq_point = int(sr / 2)
                max_freq = sr / 2
                freq_points = 700 * (np.power(10, np.linspace(0, 2595 * np.log10(1 + max_freq/700), length)/2595) - 1)
                freq_point = freq_points[int(length * freq)]
                freqs = np.linspace(0,max_freq,max_freq_point)
                return freqs[int(freq_point)]
    
            #将鼠标在频谱上点击的x轴位置,即一个[0,1]之间的数,映射到音频时间,后续用于音频切片
            xsize=self.__R * self.__freq.shape[0]
            xposeStart=xsize*xposeStart
            xposeEnd=xsize*xposeEnd
    
            yposeNow=float(yposeStart)
            width=float(sizeFreq)/200	#将滤波器宽度映射到[0,1]的尺度上
    		
            #计算滤波器的两个截止频率
            low=yposeNow-width
            high=yposeNow+width
    
            #获取滤波器并进行滤波
            if erase:
                if low>0 and high<1:
                    filt = lambda x: bandStopButterN(x, n, freq_transform(low), freq_transform(high))
                if low<=0:
                    filt = lambda x: highPassButterN(x, n, freq_transform(high))
                if high>=1:
                    filt = lambda x: lowPassButterN(x, n, freq_transform(low))
            else:
                if low>0 and high<1:
                    filt = lambda x: bandPassButterN(x, n, freq_transform(low), freq_transform(high))
                if low<=0:
                    filt = lambda x: lowPassButterN(x, n, freq_transform(high))
                if high>=1:
                    filt = lambda x: highPassButterN(x, n, freq_transform(low))
            if xposeStart<xposeEnd:
                self.__wav[xposeStart:xposeEnd]=filt(self.__wav[xposeStart:xposeEnd])
            if xposeEnd<xposeStart:
                self.__wav[xposeEnd:xposeStart]=filt(self.__wav[xposeEnd:xposeStart])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
  • 相关阅读:
    Linux、Unix、WindowsC语言理解查看字节序排序
    pytorch 查看GPU信息
    研究生英语复习(一)
    神经网络训练图形分析,神经网络训练图形分类
    1.3.19 网络端口地址转换 NAPT 配置
    【3D建模实战】维京海盗盾牌教程
    常见排序算法讲解(图解+代码+代码讲解)
    知识引擎藏经阁天花板——高性能Java架构核心原理手册
    【JAVA类】利用接口的多继承实现———图书管理系统【附源码】
    解决MySQL大版本升级导致.Net(C#)程序连接报错问题
  • 原文地址:https://blog.csdn.net/weixin_43441742/article/details/126093811