C# 电吉他音高跟踪时如何检测弦?

C# 电吉他音高跟踪时如何检测弦?,c#,audio,fft,guitar,pitch-tracking,C#,Audio,Fft,Guitar,Pitch Tracking,大家好,我是一名音频相关编码方面的noob,我在一个音高跟踪DLL中工作,我将尝试创建一种开源版本的视频游戏Rocksmith作为学习体验 到目前为止,我已经设法让FFT工作,这样我可以检测基音频率(Hz),然后通过使用算法和下表,我可以设法确定播放的音符的倍频程(2到6)和音符(C到B) 下一步是检测字符串,以便确定fret 我一直在考虑这个问题,理论上我可以这样做,我会知道用户何时弹奏正确的音符,但游戏可能是“黑客”,因为仅使用Hz,游戏无法检测音符是否以正确的字符串播放。例如5th串+1

大家好,我是一名音频相关编码方面的noob,我在一个音高跟踪DLL中工作,我将尝试创建一种开源版本的视频游戏Rocksmith作为学习体验

到目前为止,我已经设法让FFT工作,这样我可以检测基音频率(Hz),然后通过使用算法和下表,我可以设法确定播放的音符的倍频程(2到6)和音符(C到B)

下一步是检测字符串,以便确定fret

我一直在考虑这个问题,理论上我可以这样做,我会知道用户何时弹奏正确的音符,但游戏可能是“黑客”,因为仅使用Hz,游戏无法检测音符是否以正确的字符串播放。例如5th串+1th fret=C4261.63Hz等于6th串+5th fret=C4261.63Hz

让用户用错误的字符串弹奏音符并将其正确弹奏的可能性很低,但我认为了解字符串会非常好,这样当用户弹奏错误的字符串时,我可以向他们提供一些错误反馈(比如你应该向上或向下弹奏一个字符串)

你知道我能做些什么来检测字符串吗?提前感谢:)

[编辑]

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


“吉他音色的变化是由大量因素造成的,这些因素包括拾音器的设计和位置、吉他中使用的木材(这是一种不同的木材)所产生的自然共振和阻尼它的结构和形状,你琴弦的规格和年龄,你的演奏技巧,你拨弄琴弦的地方,等等。”

由于许多潜在的强泛音,一个简单的FFT峰值估计器不是一个好的吉他音高检测器/估计器。目前存在更为稳健的基音估计算法(search-stackoverflow和DSP.stackexchange)。但是,如果你要求玩家在游戏开始前,在他们各自的乐器上预先描绘出每根弦的特征,无论是开放的还是烦躁的,这些特征的FFT指纹可能能够区分在某些吉他上不同弦上演奏的同一音符。较粗的弦在某些较高的泛音中会发出稍微不同的能量比率,以及不同数量的轻微不和谐。

其他答案似乎表明了一种简单的音调检测方法。然而,这是你必须研究的


具体地说,比较第五弦第一格和第六弦第五格的泛音。也就是说,只看261.63*2、261.63*3、*4等等。另外,试着看261.63*0.5。比较两个信号在这些频率下的振幅。可能存在可以检测到的模式。

这可能有点晚,因为帖子已经发布一年了。但这里有一个解决方案,这是我在长期研究检测吉他音高后发现的

这就是FFT不起作用的原因:

您不能使用FFT,因为结果为您提供了一个线性阵列,并且声音是按对数计算的(音符之间的指数距离)。另外,FFT会给你一系列的桶,你的频率可能在其中,但它不会给你精确的结果

这就是我的建议:

使用dywapitchtrack。这是一个使用小波算法的库,它直接作用于你的波,而不是像FFT那样计算大型容器

说明: dywapitchtrack基于定制的算法,该算法具有非常高的质量: 非常准确(精度<0.05半音)、非常低的延迟(<23毫秒)和 非常低的错误率。它已经在人声上进行了彻底的测试。 最好将其描述为动态小波算法(dywa):

下载:

使用(C++): 将.c和.h放在需要的地方,并将其导入到项目中

包括头文件

//Create a dywapitchtracker Object
dywapitchtracker pitchtracker;

//Initialise the object with this function
dywapitch_inittracking(&pitchtracker);
当您的缓冲区已满时(缓冲区需要44100分辨率和长度的2倍幂,我的是2048):


瞧,这块蛋糕正好包含了你需要的东西。(如果有不清楚的地方,请随时提问)

我不确定这是否可行,因为如果调整得当,两个字符串将发出相同的音符。我不知道在这一点上,计算机是否能检测到音色的差异。同意诺沃德的观点-同一个音符在较低的弦上演奏时会有不同的(稍微柔和)音色,但我怀疑你是否有足够的运气检测到这一点-在一个已知的乐器上可能会稍微容易一些。我想你对定制皮卡不感兴趣吧?:)我将使用这只电吉他与标准的调整。从一个快速的研究看来,音色检测是一个太复杂的任务。。。我可能需要创建一个算法,通过将播放的音符与预期音符附近的音符进行比较,尽可能地识别用户错误。有一些基于FFT的f0估计算法工作得很好(例如Maher和Beauchamp的“双向失配程序”JASA 04 1994)。您可能想更正您的答案,说“FFT上简单的峰值拾取不是一个好的基音检测器”。完成。FFT可以作为更稳健的复合估计方法(倒谱等)的简单第一步。我有一个问题。dywapitchtracker库是一颗宝石,但它似乎无法在未初始化时释放内存。知道为什么吗?
//use this function with your buffer
double thePitch = dywapitch_computepitch(&pitchtracker, yourBuffer, 0, 2048);