我花了很多年研究复调音乐的音高检测——比如检测 mp3 录音中吉他独奏的音符。我还在 Wikipedia 上写了一个部分,简要描述了该过程(查看下面链接中的“音高检测”小节)。
当在钢琴上按下一个键时,我们听到的不仅仅是一个声音振动频率,而是在不同数学相关频率上发生的多个声音振动的复合。这种不同频率的振动复合的元素被称为谐波或分音。例如,如果我们按下钢琴上的中间 C 键,复合谐波的各个频率将从 261.6 Hz 作为基频开始,523 Hz 将是 2 次谐波,785 Hz 将是 3 次谐波,1046 Hz 将是 4 次谐波等。后面的谐波是基频 261.6 Hz 的整数倍(例如:2 x 261.6 = 523、3 x 261.6 = 785、4 x 261.6 = 1046)。
我使用修改后的 DFT 对数变换首先通过寻找具有峰值电平的频率来检测可能的谐波(见下图)。由于我为修改后的 Log DFT 收集数据的方式,我不必对信号应用 Windowing Function,也不必add 和 overlay。我创建了 DFT,因此它的频率通道以对数方式定位,以便直接与吉他、萨克斯管等音符产生的谐波频率对齐。
现在退休了,我决定在一个名为PitchScope Player的免费演示应用程序中发布我的音高检测引擎的源代码。PitchScope Player 可在网络上获得,您可以下载适用于 Windows 的可执行文件,以查看我的算法在您选择的 mp3 文件上的运行情况。以下指向 GitHub.com 的链接将引导您访问我的完整源代码,您可以在其中查看我如何使用自定义对数 DFT 变换检测谐波,然后查找其频率满足定义了正确整数关系的部分(谐波)'沥青'。
我的音高检测算法实际上是一个两阶段的过程:a)首先检测到ScalePitch('ScalePitch' 有 12 个可能的音高值:{E、F、F#、G、G#、A、A#、B、C、C#、D , D#} ) b) 并且在确定 ScalePitch 之后,通过检查 4 个可能的 Octave-Candidate 音符的所有谐波来计算 Octave 。该算法旨在检测和弦 MP3 文件中任何给定时刻的最主要音高(音符)。这通常对应于器乐独奏的音符。那些对我的 2 阶段音高检测算法的 C++ 源代码感兴趣的人可能希望从 GitHub.com 上的 SPitchCalc.cpp 文件中的 Estimate_ScalePitch() 函数开始。
https://github.com/CreativeDetectors/PitchScope_Player
https://en.wikipedia.org/wiki/Transcription_(music)#Pitch_detection
下面是对数 DFT(由我的 C++ 软件创建)在复音 mp3 录音中吉他独奏 3 秒的图像。它显示了演奏独奏时吉他上各个音符的谐波如何出现。对于这个对数 DFT 上的每个音符,我们可以看到它的多个谐波垂直延伸,因为每个谐波将具有相同的时间宽度。确定音符的八度后,我们就知道了基本音的频率。
下图演示了八度检测算法,一旦确定了该音符的 ScalePitch,我开发该算法以选择正确的八度候选音符(即正确的基本音)。那些希望在 C++ 中看到该方法的人应该转到名为 FundCandidCalcer.cpp 的文件中的 Calc_Best_Octave_Candidate() 函数,该文件包含在我在 GitHub 的源代码中。