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

Python 我的笔记检测算法在少数情况下失败?,python,python-2.7,signal-processing,fft,audio-processing,Python,Python 2.7,Signal Processing,Fft,Audio Processing,我使用一种简单的方法在python中使用FFT查找音符 涉及的步骤包括: 读取声音文件(.wave) 检测文件中的静默(通过计算窗口内输入的平方元素的平方和) 使用从(2)中获得的数据检测注释的位置 使用DFT计算每个检测到的音符的频率 将计算的频率与音符的标准频率相匹配,以识别正在播放的音符 但是在一个音符应该是A4/440hz的情况下,我得到了一个巨大的变化(2kHz) 我的方法有什么根本性的错误吗 更新:如何将我的audio.wav文件传递给此文件 完整的python代码是 window_

我使用一种简单的方法在python中使用FFT查找音符 涉及的步骤包括:

  • 读取声音文件(.wave)
  • 检测文件中的静默(通过计算窗口内输入的平方元素的平方和)
  • 使用从(2)中获得的数据检测注释的位置
  • 使用DFT计算每个检测到的音符的频率
  • 将计算的频率与音符的标准频率相匹配,以识别正在播放的音符
  • 但是在一个音符应该是A4/440hz的情况下,我得到了一个巨大的变化(2kHz) 我的方法有什么根本性的错误吗

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

    完整的python代码是

    window_size=2000#用于检测静音的窗口大小
    beta=1#静音检测参数
    max_notes=100#为提高效率,文件中的最大注释数
    采样频率=44100#音频信号的采样频率
    阈值=200
    #使用固定窗口大小遍历声音方阵列
    而(idft[-1]和dft[1]>dft[-1]):
    i_max=dft[-1]
    elif(dft[1]>dft[0]和dft[-1]>dft[0]):
    i_max=dft[0]
    其他:
    i_max=dft[1]
    #碰撞频率
    频率。附加((i_max*采样频率)/(i-k))
    dft=[]
    k=i+1
    i=i+窗口大小
    
    基音与FFT的峰值幅值频率间隔不同。音高是人类的一种心理声学现象。音高声音可能缺少或非常弱的基音(在某些声音、钢琴和吉他声音中很常见)和/或在其频谱中有许多强大的泛音,这些泛音压倒了音高频率(但仍然可以被人类听到作为音高音符)。因此,任何FFT峰值频率检测器(甚至包括一些加窗和插值,您的代码没有)都不会是一种稳健的音高估计方法。FFT还将根据FFT(或窗口)长度将频率量化为某种面元分辨率(可能比您的要求更粗糙)


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

    音高跟踪在librosa.piptrack中实现

    您假设频谱中最高幅值峰值的频率对应于音符的音调-在某些情况下可能是正确的,但一般情况下并非如此。请参阅StackOverflow上的许多其他类似问题,以全面讨论为什么音调检测比您想象的要复杂得多。@PaulR这就是我们被指示要做的。如果你能告诉我你在谈论哪个问题,我将不胜感激。你能提供这个链接吗?之前有很多问题——似乎实现吉他调谐器和其他类似的音高检测应用程序是本科生的热门项目选择。只要搜索“吉他调谐器”或“音高检测”以及
    [fft]
    标记,您就会找到很多相关信息。@PaulR您能告诉我如何传递audio.wav以查看freq\u estimator.py是否有效吗?请遵守“每个问题一个问题”的规则-看起来你的更新应该是一个单独的问题。
    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