滤波器设计以在特定音频频率下找到能量

时间:2013-07-24 17:54:46

标签: python scipy filtering signal-processing

我正在调整并将MeinardMüller和Sebastien Ewert的Matlab“Chroma Toolbox”扩展到python。它旨在检测每个分析帧中存在的音乐音高以进行录音。

第一步是确定音乐的调音,而Chroma Toolbox测试音乐是按照标准A = 440Hz,还是按四分之一,三分之一,三分之二或四分之三调低一个半音。没关系,但在我的应用程序中,我需要在调优检测中获得更高的分辨率。

一旦从这些选择之一中选择了调谐,就选择相应的滤波器组,用于找出在钢琴范围内每个音调上有多少能量。 (此外,波形重新采样为22050,4410和882 Hz)

滤波器组的系数存储在.mat文件中,由Chroma Toolbox给出。例如,在标准调谐的中间C(261.63Hz)处检测能量的系数是b = [1.,-7.43749873,24.72954997,-47.94740681,59.25189976,  -47.77885707,24.55599193,-7.35933913,0.98601284]和= [0.00314443,-0.02341175,0.07794208,-0.15134062,0.18733283,-0.15134062,0.07794208,-0.02341175,0.00314443],和用于中央C的采样速率为4410赫兹。

这些系数在呼叫用于filtfilt:我用scipy.signal.filtfilt(B,A,x),其中x是在适当的采样频率的波形,低的低音符,高为更高的。此步骤在文件“audio_to_pitch_via_FB.m”中完成。

问题:

因为我想允许不同于色度工具箱中设计的调整级别,我需要制作自己的滤波器组,因此需要知道如何计算滤波器系数。为此,我需要一个函数 coeffs(freq,fs),它将找到正确的系数来找到给定频率 freq 的能量,对于采样频率的信号 FS 。我该怎么做?

以下是其中一个.mat文件的名称,以防它包含有用的线索。 “MIDI_FB_ellip_pitch_60_96_22050_Q25_minusQuarter.mat”

1 个答案:

答案 0 :(得分:2)

生成过滤器的代码位于generateMultiratePitchFilterbank.m文件中。省略函数以相反的方式返回a和b,但是否则它或多或少相同。

以下配方会重现您引用的数字:

import numpy as np
import scipy.signal as ss

def coeffs(pitch, fs, Q=25, stop=2, Rp=1, Rs=50):
    """Calculate filter coeffs for a given pitch and sampling rate, fs.
    See their source code for description of Q, stop, Rp, Rs"""
    nyq = fs/2.                       # Nyquist frequency
    pass_rel = 1/(2.*Q)             
    stop_rel = pass_rel * stop

    # The min-max edges of the pass band
    Wp = np.array([pitch - pass_rel*pitch, pitch+pass_rel*pitch])/nyq
    # And the stop band(s)
    Ws = np.array([pitch - stop_rel*pitch, pitch+stop_rel*pitch])/nyq

    # Get the order, natural freq
    n, Wn = ss.ellipord(Wp, Ws, Rp, Rs)

    # Get a and b:
    a, b = ss.ellip(n, Rp, Rs, Wn, btype="bandpass")

    return a, b