如何在电吉他音高跟踪时检测字符串?

9

你好,我是一个音频编码方面的新手,正在开发一个音高追踪DLL,我将使用它来尝试创建一种类似于视频游戏Rocksmith的开源版本,以此作为学习经验。

到目前为止,我已经成功地让FFT工作了,所以我可以检测出音高频率(Hz),然后通过使用算法和下表,我可以确定演奏音符的八度(2至6)和音符(C至B)。

下一步是检测弦,以便我可以确定品位。

enter image description here

我一直在思考,在理论上,我可以处理这个问题,我将知道用户何时演奏正确的音符,但是游戏可能会被“黑客攻击”,因为仅使用Hz,游戏无法检测是否在正确的弦上演奏音符。例如第五弦+第一品位=C4 261.63Hz等同于第六弦+第五品位=C4 261.63Hz

用户在错误的弦上演奏正确的音符并得分的机会很低,但我认为了解弦很重要,这样我就可以在他们弹奏错误的弦时向用户提供一些错误反馈(例如,您应该向上或向下移动弦)。

你知道我能做什么来检测弦吗?先谢谢了:)

[编辑]

我们使用的吉他和琴弦会影响音色,因此分析音色似乎不是检测弦的简单方法:

"吉他音色的变化由许多因素产生,包括拾音器的设计和位置、由于所使用的木材(这是一种不同类型的木材!)以及其结构和形状而产生的自然共鸣和阻尼、弦的规格和年龄、您的演奏技巧、您按弦和弹弦的位置等等。"


4
我不确定这是否可能,因为如果正确调音,则两个琴弦会发出相同的音符。我不知道计算机是否能够在目前检测到音色上的差异。 - NWard
2
同意NWard的观点 - 当在低音弦上演奏相同的音符时,它们会有不同(稍微柔和)的音色,但我怀疑你很难检测到这一点 - 在单个已知乐器上可能会稍微容易一些。我假设你不想制作定制拾音器? :) - Нет войне
我只会将其用于标准调弦的电吉他。通过快速的研究,似乎音色检测是一个过于复杂的任务... 我可能需要创建一个算法,尽最大努力通过将所弹奏的音符与期望音符附近的音符进行比较来识别用户的错误。 - Remo H. Jansen
3个回答

3
这可能有点晚,因为这篇文章已经一年了。但是这里有一个解决方案,我在长时间研究吉他音高检测后发现的。
FFT为什么不起作用:
你不能使用FFT,因为其结果会给出一个线性数组,而声音是按对数计算的(音符之间的指数距离)。另外,FFT给出的是频率可能存在的一组bin,它并没有给出精确的结果。
我建议的方法:
使用dywapitchtrack。它是一个库,使用小波算法直接处理您的波形,而不是像FFT那样计算大的bins。
描述:
dywapitchtrack基于一个定制的算法,质量非常高:精度非常高(精度<0.05个半音),延迟非常低(<23ms),错误率非常低。它已经在人的声音上进行了彻底的测试。最好将其描述为动态小波算法(dywa)。

下载: https://github.com/inniyah/sndpeek/tree/master/src/dywapitchtrack

使用(C++): 将.c和.h文件放在所需位置,并在项目中导入

包含头文件

//Create a dywapitchtracker Object
dywapitchtracker pitchtracker;

//Initialise the object with this function
dywapitch_inittracking(&pitchtracker);

当你的缓冲区满时(缓冲区需要以44100分辨率和长度为2的幂,我的长度是2048):

//use this function with your buffer
double thePitch = dywapitch_computepitch(&pitchtracker, yourBuffer, 0, 2048);

瞧,thePitch 正好包含了你所需的内容。(如果有不清楚的地方,请随时提问)


我有一个问题。dywapitchtracker 库是一颗宝石,但似乎在未初始化时不会释放内存。你有什么想法吗? - cassi.lup

2
一个简单的FFT峰值估计器不是一个好的吉他音高检测/估计器,因为存在许多潜在的强倍频。存在更加健壮的音高估计算法(搜索stackoverflow和DSP.stackexchange)。但是,如果您要求玩家在开始游戏之前对其个人乐器上的每个弦进行预特征化,包括开放和按弦的,那么这些特征化的FFT指纹可能能够区分不同吉他上播放的相同音符。较粗的弦将会在一些较高的倍频中发出略微不同的能量比例,以及不同数量的轻微失谐。

1
有基于FFT的f0估计算法表现良好(例如Maher和Beauchamp的“双向不匹配过程”JASA 04 1994)。您可能需要更正您的答案,以便说“在FFT上进行简单的峰值拾取不是一个好的音高检测器”。 - Ross Bencina
1
完成。FFT 可以作为更强大的复合估计方法(倒谱等)的微不足道的第一步。 - hotpaw2

0

其他答案似乎建议使用简单的音高检测方法。然而,这是你需要研究的东西。

具体来说,比较第五弦第一品位和第六弦第五品位的泛音。也就是说,只看261.63*2、261.63*3、*4等频率。此外,尝试查看261.63*0.5。比较这些频率下两个信号的振幅。可能会有一种可以检测到的模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接