P i*_*P i 3 iphone algorithm signal-processing detection pitch
我想要检测的不是音高,而是发出唱音的音高等级.
因此,无论是C4还是C5都不重要:它们必须都被检测为C.
想象一下,12个半音安排在钟面上,针指向音高等级.这就是我追求的!理想情况下,我希望能够分辨出唱歌音符是点亮还是稍微偏离.
这与先前提出的问题不重复,因为它引入了以下约束条件:
声源是一个人的声音,希望背景干扰可以忽略不计(虽然我可能需要处理这个问题)
八度音阶并不重要,只有音高等级
编辑 - 链接:
实时音高检测
使用Apple FFT和加速框架
见我的答案在这里为获得平滑的频率检测:/sf/answers/772978601/
至于将此频率捕捉到最近的音符 - 这是我为调谐器应用创建的方法:
- (int) snapFreqToMIDI: (float) frequencyy {
int midiNote = (12*(log10(frequencyy/referenceA)/log10(2)) + 57) + 0.5;
return midiNote;
}
Run Code Online (Sandbox Code Playgroud)
这将返回MIDI音符值(http://www.phys.unsw.edu.au/jw/notes.html)
为了从此MIDI音符值中获取字符串:
- (NSString*) midiToString: (int) midiNote {
NSArray *noteStrings = [[NSArray alloc] initWithObjects:@"C", @"C#", @"D", @"D#", @"E", @"F", @"F#", @"G", @"G#", @"A", @"A#", @"B", nil];
return [noteStrings objectAtIndex:midiNote%12];
}
Run Code Online (Sandbox Code Playgroud)
有关使用输出平滑的音调检测的示例实现,请查看musicianskit.com/developer.php
其他答案中引用的大多数频率检测算法都不适用于语音。要直观地理解为什么会出现这种情况,请考虑一种语言中的所有元音都可以用一个特定的音符来演唱。尽管所有这些元音具有非常不同的频率内容,但它们都必须被检测为相同的音符。任何语音音符检测算法都必须以某种方式考虑到这一点。此外,人类的言语和歌曲包含许多摩擦音,其中许多没有隐含的音高。
在通用(非语音情况)中,您正在寻找的功能称为色度功能,并且关于该主题有相当多的工作。它相当于谐波音级曲线。关于这个概念的原始参考论文是 Tayuka Fujishima 的“音乐声音的实时和弦识别:使用 Common Lisp 音乐的系统”。维基百科条目概述了该算法的更现代的变体。有大量关于色度特征检测的免费论文和 MATLAB 实现。
然而,由于您只关注人声,并且人声自然包含大量泛音,因此在这个特定场景中您实际上需要的是基频检测算法,或f0 检测算法。有几种这样的算法明确针对语音进行了调整。此外,这里还有一个被广泛引用的算法,可以同时处理多个语音。然后,您将根据等律音阶检查检测到的频率,然后找到最接近的匹配。
由于我怀疑您正在尝试构建一个自动调谐的音调检测器和/或校正器,因此您可能需要使用 M. Morise 出色的WORLD实现,它允许对语音流上的 f0 进行快速且高质量的检测和修改。
最后,请注意,只有少数音高检测器可以在人声音域中正常工作。几乎所有这些,包括 WORLD,在声音炸裂和非常低的声音方面都失败了。许多论文将发声弗莱称为“吱吱作响的声音”,并开发了特定的算法来专门帮助处理这种类型的语音输入。