Python中的音高检测

17

我正在开发一个Python模块的概念,它可以检测特定频率(人类语音频率80-300hz),并通过从数据库中检查来显示句子的语调。我使用SciPy绘制声音文件的频率,但我无法设置任何特定的频率以分析音高。我该怎么做?

更多信息:我想能够设置一种定义好的语音模式(例如上升、下降),并且程序会检测声音文件是否遵循特定的模式。


你的意思是不能按顺序设置任何频率吗?你能否详细描述一下你现在正在做什么? - Sahil M
我想使用Scipy(或其他库)来响应特定频率(人类语音),以便它可以指示音高(请参见PRAAT软件)。通过这样做,我希望我的程序能够指示句子的语调(虽然它可能不是那么准确,但对于语言学研究来说已经足够了)。@SahilM - Andrew Ravus
4个回答

20

更新于2019年,现在有基于神经网络的非常准确的音高跟踪器。而且它们可以直接在Python中使用。请查看https://pypi.org/project/crepe/

来自2015年的回答。音高检测是一个复杂的问题,谷歌最新的软件包为这个非常棘手的任务提供了高度智能的解决方案:

https://github.com/google/REAPER

你可以将其封装在Python中,如果你想从Python中访问它。


Shimyrev,你会如何将这个包装成Python? - Dole
1
https://dev59.com/Z3I-5IYBdhLWcg3wQWCc - Nikolay Shmyrev

13

您可以尝试以下方法。我相信您知道人类声音也有超过300赫兹的谐波。尽管如此,您可以在音频文件上移动窗口,并尝试查看最大功率(如下所示)或窗口中一组频率的功率变化。以下代码旨在提供直觉:

import scipy.fftpack as sf
import numpy as np
def maxFrequency(X, F_sample, Low_cutoff=80, High_cutoff= 300):
        """ Searching presence of frequencies on a real signal using FFT
        Inputs
        =======
        X: 1-D numpy array, the real time domain audio signal (single channel time series)
        Low_cutoff: float, frequency components below this frequency will not pass the filter (physical frequency in unit of Hz)
        High_cutoff: float, frequency components above this frequency will not pass the filter (physical frequency in unit of Hz)
        F_sample: float, the sampling frequency of the signal (physical frequency in unit of Hz)
        """        

        M = X.size # let M be the length of the time series
        Spectrum = sf.rfft(X, n=M) 
        [Low_cutoff, High_cutoff, F_sample] = map(float, [Low_cutoff, High_cutoff, F_sample])

        #Convert cutoff frequencies into points on spectrum
        [Low_point, High_point] = map(lambda F: F/F_sample * M, [Low_cutoff, High_cutoff])

        maximumFrequency = np.where(Spectrum == np.max(Spectrum[Low_point : High_point])) # Calculating which frequency has max power.

        return maximumFrequency

voiceVector = []
for window in fullAudio: # Run a window of appropriate length across the audio file
    voiceVector.append (maxFrequency( window, samplingRate))

现在根据语音的语调,最大功率频率可能会发生偏移,您可以注册并映射到给定的语调。这不一定总是正确的,您可能需要同时监测许多频率的变化,但这应该可以帮助您入门。


1
我已经添加了需要导入的模块,它使用了scipy fftpack和numpy。 - Sahil M
1
音高与最大功率无关。 - Nikolay Shmyrev

6

3
基本上有两类f0(音高)估计方法:时域方法(如自相关/互相关),和频域方法(如通过测量谐波之间的距离来识别基频,或在频谱中识别具有最大功率的频率,正如Sahil M在上面的例子中所示)。多年来,我一直成功地使用了RAPT(稳健的音高跟踪算法),它是REAPER的前身,也由David Talkin开发。你提到的广泛使用的Praat软件也包括类似于RAPT的互相关算法选项。描述和代码可以轻松地在网络上找到。DEB安装归档文件可以在这里找到:http://www.phon.ox.ac.uk/releases 。利用音高函数进行模式检测(上升、下降等)是一个独立的问题。Sahil M上面提出的使用移动窗口跨越音高函数的建议是一个很好的起点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接