Librosa音高跟踪 - STFT

pav*_*163 13 python signal-processing pitch-tracking librosa

我正在使用算法来检测音频文件的音高 .正如您所听到的,它是在吉他上播放的E2音符,背景中有一点噪音.

我使用STFT生成了这个频谱图:频谱

我正在使用上面链接的算法,如下所示:

y, sr = librosa.load(filename, sr=40000)
pitches, magnitudes = librosa.core.piptrack(y=y, sr=sr, fmin=75, fmax=1600)

np.set_printoptions(threshold=np.nan)
print pitches[np.nonzero(pitches)]
Run Code Online (Sandbox Code Playgroud)

结果,我fmin和我之间几乎可以获得所有可能的频率fmax.我该如何处理piptrack方法的输出以发现时间范围的基本频率?

UPDATE

不过,我仍然不确定这些2D数组代表什么.假设我想知道第5帧中82Hz的强度.我可以使用STFT函数来做到这一点,它只返回一个2D矩阵(用于绘制频谱图).

但是,piptrack做一些额外的事情可能是有用的,我真的不明白什么.pitches[f, t] contains instantaneous frequency at bin f, time t.这是否意味着,如果我想在时间帧t找到最大频率,我必须:

  1. 转到magnitudes[][t]数组,找到具有最大幅度的bin.
  2. 将bin分配给变量f.
  3. 找到pitches[b][t]找到属于该bin的频率?

Jam*_*ard 8

音高检测是一个棘手的话题,通常是违反直觉的.我对于为这个特定功能记录源代码的方式并不狂热 - 开发人员似乎很混淆'调和'与'音调'.

当在吉他或钢琴上制作单个音符("音调")时,我们听到的不仅仅是声音振动的一个频率,而是在不同的数学相关频率上发生的多个声音振动的复合,称为谐波.典型的音调跟踪技术包括搜索FFT的结果,以获得对应于谐波的预期频率的某些箱中的幅度.例如,如果我们按下钢琴上的中间C键,复合谐波的各个频率将以261.6 Hz开始作为基频,523 Hz将是2次谐波,785 Hz将是3次谐波,1046 Hz将是后谐波是基频的整数倍,261.6 Hz(例如:2 x 261.6 = 523,3 x 261.6 = 785,4 x 261.6 = 1046).然而,谐波所处的频率是对数间隔的,但FFT使用线性间隔.通常,在较低频率下,FFT的垂直间距不够充分.

出于这个原因,当我编写一个音高检测应用程序(PitchScope Player)时,我选择创建一个对数间隔的DFT,而不是FFT,因此我可以专注于音乐感兴趣的精确频率(参见我自定义DFT的附图)从3秒的吉他独奏).如果你认真考虑进行音高检测,你应该考虑更多地阅读这个主题,查看其他示例代码(我的链接如下),并考虑编写自己的函数来测量频率.

https://en.wikipedia.org/wiki/Transcription_(music)#Pitch_detection

https://github.com/CreativeDetectors/PitchScope_Player

在此输入图像描述


pav*_*163 5

事实证明,在特定帧处拾取音高的方法t很简单:

def detect_pitch(y, sr, t):
  index = magnitudes[:, t].argmax()
  pitch = pitches[index, t]

  return pitch
Run Code Online (Sandbox Code Playgroud)

首先通过查看magnitudes阵列来获得最强频率的频率,然后在处找到音调pitches[index, t]