多音调检测:FFT还是其他?

时间:2012-03-08 06:31:08

标签: c++ signal-processing fft pitch

我研究过快速傅立叶变换,但却未能看到它们从一个信号中解码多个频率的方法。有没有办法分解fft计算的结果,以便我们可以在和弦中看到单个音高,或者根据fft的结果计算最可能的和弦?

如果没有,是否有另一种音高检测方法可以检测实时设置中的多个音高?

编辑:我试图一次不超过六个音高,因为我写的软件涉及吉他;在程序用户使用七弦吉他的情况下,它需要能够最多拾取七个音高。

在这种情况下,是一种FFT(或其他方法)能够从单个麦克风信号处理这个问题,还是我必须制作一个单独读取每个字符串的吉他拾音器?

3 个答案:

答案 0 :(得分:3)

参数谱估计有两种众所周知的统计技术。一个是MUSIC 另一个是ESPRIT。如果您可以将您的信号表示为加权复指数(即正弦波)的总和,则可以应用其中任何一个。此外,相关矩阵的特征分解也会告诉你信号中的频率数,所以你甚至不应该知道。 ESPRIT比MUSIC更好,因为你不应该在频域搜索峰值。结果直接给出了频率。然而,众所周知,MUSIC更强大。

答案 1 :(得分:1)

可能需要一个隔离每根弦的吉他拾音器。否则,所有泛音的混合可能是一个非常困难的问题。

答案 2 :(得分:1)

您首先需要了解'音高'的真实含义(请阅读下面的维基百科链接)。当在吉他或钢琴上制作单个音符时,我们听到的不仅仅是声音振动的一个频率,而是在不同的数学相关频率上发生的多个声音振动的复合。这种不同频率的振动合成元素被称为谐波或部分。例如,如果我们按下钢琴上的中间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)。

下面,在GitHub.com上,我设计了一个不寻常的两阶段算法的C ++源代码,它可以在Windows上播放时对复音MP3文件进行实时音高检测。这种免费应用程序(PitchScope Player,可在网上获得)经常用于在MP3录制时检测吉他或萨克斯独奏的音符。您可以下载Windows的可执行文件,以便在您选择的mp3文件上查看我的算法。该算法被设计成在MP3或WAV音乐文件中的任何给定时刻检测最主要的音调(音符)。通过在MP3录制期间的任何给定时刻的最主要音高(音符)的变化来准确地推断音符开始。

我使用改进的DFT对数变换(类似于FFT)来首先通过查找具有峰值电平的频率来检测这些可能的谐波(参见下图)。由于我为修改后的Log DFT收集数据的方式,我不必对信号应用窗口函数,也不必添加和重叠。我创建了DFT,因此它的频道以对数方式定位,以便直接与吉他,萨克斯管等音符创建谐波的频率对齐。

我的音高检测算法实际上是一个两阶段过程:a)首先检测ScalePitch('ScalePitch'有12个可能的音高值:{E,F,F#,G,G#,A,A#,B,C, C#,D,D#})b)并且在确定ScalePitch之后,通过检查4种可能的Octave-Candidate音符的所有谐波来计算Octave。该算法旨在检测复音MP3文件中任何给定时刻的最主要音高(音符)。这通常对应于乐器独奏的音符。那些对我的Two Stage Pitch Detection算法的C ++源代码感兴趣的人可能想从GitHub.com的SPitchCalc.cpp文件中的Estimate_ScalePitch()函数开始。

https://github.com/CreativeDetectors/PitchScope_Player

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

enter image description here