我正在调整并将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”
答案 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