Android中的吉他音高检测

时间:2017-01-15 07:49:15

标签: android real-time fft frequency-analysis pitch-tracking

我尝试在Android平台上开发吉他游戏。

我需要进行实时音高检测以获得吉他和弦/弦的频率。

我将从麦克风获取输入,然后分析输入(输入播放哪种吉他弦/和弦)

我找到了两种可以使用的方法,一种是YIN,另一种是FFT。

哪种方法可以获得更好的性能和准确的结果?

1 个答案:

答案 0 :(得分:3)

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

以下是对数DFT(由我的C ++软件创建)在复音mp3录音中进行3秒钟吉他独奏的图像。它显示了在演奏独奏时吉他上各个音符的谐波是如何出现的。对于此对数DFT上的每个音符,我们可以看到它的多个谐波垂直延伸,因为每个谐波将具有相同的时间宽度。在确定音符的八度音符之后,我们知道基音的频率。

enter image description here

下图演示了Octave Detection算法,我开发该算法,一旦确定了该音符的ScalePitch,就选择正确的Octave-Candidate音符(即正确的基本音符)。那些希望在C ++中看到该方法的人应该转到名为FundCandidCalcer.cpp的文件中的Calc_Best_Octave_Candidate()函数,该函数包含在GitHub的源代码中。

enter image description here