2

我正在将Meinard Müller 和 Sebastien Ewert的 Matlab“色度工具箱”改编并扩展到 python。它旨在检测音频记录的每个分析帧中存在哪些音高。

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

一旦从其中一个选项中选择了调音,就会选择相应的滤波器组,用于确定钢琴范围内每个音高的能量。(此外,波形被重新采样为 22050、4410 和 882 Hz)

滤波器组的系数存储在 .mat 文件中,由 Chroma Toolbox 提供。例如,在标准调谐中间 C (261.63 Hz) 处检测能量的系数为 b = [ 1., -7.43749873, 24.72954997, -47.94740681, 59.25189976, -47.77885707, 24.55599193, -7.35903144, 34 = [6] [1., -7.35903144, 34] [0.9]。 , -0.02341175, 0.07794208, -0.15134062, 0.18733283, -0.15134062, 0.07794208, -0.02341175, 0.00314443],中间 C 的采样率为 4410 Hz。

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

问题:

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

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

4

1 回答 1

2

生成过滤器的代码位于 generateMultiratePitchFilterbank.m 文件中。ellip 函数以相反的方式返回 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
于 2013-07-25T10:12:33.353 回答