我的笔记检测算法在少数情况下失败?

时间:2018-11-14 11:52:08

标签: python python-2.7 signal-processing fft audio-processing

我正在使用一种简单的方法在python中使用FFT找出音符 涉及的步骤是:

  1. 读取声音文件(.wave)
  2. 检测文件中的静音(通过计算落入窗口中的输入平方元素的平方和)
  3. 使用从(2)获得的数据检测笔记的位置
  4. 使用DFT计算每个检测到的音符的频率
  5. 将计算出的频率与音符的标准频率相匹配,以识别正在播放的音符。

但是在音符应该是A4 / 440hz的情况下,我得到的变化很大(2K Hz) 我的方法有什么根本性的错误吗?

  

更新:如何将我的audio.wav文件传递到此frequency estimator

完整的python代码为here

window_size = 2000    # Size of window to be used for detecting silence
beta = 1   # Silence detection parameter
max_notes = 100    # Maximum number of notes in file, for efficiency
sampling_freq = 44100   # Sampling frequency of audio signal
threshold = 200


 # traversing sound_square array with a fixed window_size
while(i<=len(sound_square)-window_size):
    s = 0.0
    j = 0
    while(j<=window_size):
        s = s + sound_square[i+j]
        j = j + 1   
        # detecting the silence waves
    if s < threshold:
        if(i-k>window_size*4):
            dft = np.array(dft) # applying fourier transform function
            dft = np.fft.fft(sound[k:i])
            dft = np.argsort(dft)

            if(dft[0]>dft[-1] and dft[1]>dft[-1]):
                i_max = dft[-1]
            elif(dft[1]>dft[0] and dft[-1]>dft[0]):
                i_max = dft[0]
            else :  
                i_max = dft[1]
                        # claculating frequency             
            frequency.append((i_max*sampling_freq)/(i-k))
            dft = []
            k = i+1
    i = i + window_size

2 个答案:

答案 0 :(得分:0)

音调与FFT的峰值幅度频率仓不同。音调是一种人类的心理声学现象。基音可能缺少或非常弱的基音(在某些语音,钢琴和吉他声音中很常见)和/或频谱中的许多有力的泛音使基音频率不堪重负(但仍被人听到为该基音) 。因此,任何FFT峰值频率检测器(甚至包括一些开窗和内插,而您的代码不包括在内)都不是可靠的音乐音高估计方法。 FFT还会将频率量化为一定的bin分辨率(可能比您的要求更粗糙),具体取决于FFT(或窗口)的长度。

对此stackoverflow question的答案包括一些估计音高的替代方法的列表,这些方法可能会产生更好的结果。

答案 1 :(得分:0)