提取C语言中的未知模式

3
我目前正在开发一款音频处理软件,必须使用零交叉估计来检测输入信号的频率。当输入为完美的正弦波时,估计频率并不困难,但当讨论钢琴时,声波会有所不同,其背后的理论也会改变。
目前,该软件检测每个零点并保存它与前一个零点之间的索引位置(以记录经过了多少个样本)。
以下是一个数组,其中包含以44.1kHz采样的130 Hz钢琴C音符每个零点之间的样本。
44  11  36  65  56  12  37  66  52  13  38  67  51  11  39  68  50  11  47  60  49  11  48  61  47  14  47  66  43  13

任务是确定未知长度的未知模式。但这些模式可能具有误差范围。例如,
44, 11, 36, 65
56, 12, 37, 66
52, 13, 38, 67

模式是指重复出现的特定形式。因此,在处理模式的平均值之后,可以轻松检测到频率。 如果我想检测这些类型的模式,但不知道模式本身及其长度,该怎么办?


我建议您不要使用过零率来估计频率... - Oliver Charlesworth
让我想起了自相关。无论如何,你应该寻找音高检测算法。 - Alexey Frunze
实现该微处理器无法实时运行FFT,这就是为什么我正在使用ZeroX方法@OliCharlesworth。 - facandiav
1
哦,如果你不能做FFT,自相关就行不通了,因为FFT是计算它最有效的方法。我认为你在使用弱CPU时成功的机会相当渺茫。 - Alexey Frunze
你不能像这样找到所有的频率,但是你可能能够估计最低的频率。如果你有足够的样本,你可以尝试构建一个“谱图”:对于每个模式长度,绘制它的出现次数。然后从中找到可能峰值的位置。 - Archie
尝试将长度为4的向量分组,计算这些向量之间的距离度量。然后重复进行2、6、8等分组/集合,并选择具有最低和最一致距离度量的集合。 - hotpaw2
1个回答

1

您应该先尝试低通滤波您的信号。这将减少信号成分,包括导致额外零交叉的高次谐波。重点在于增加基音相对于其他谐波的强度,这些谐波实际上只是创建了无关的零交叉。

有关均衡器的一些提示:

http://blog.bjornroche.com/2012/08/basic-audio-eqs.html

关于音高检测,其中一个重要概念是等于(eq)。

http://blog.bjornroche.com/2012/07/frequency-detection-using-fft-aka-pitch.html

根据您的信号,您可能需要更陡峭的东西,比如更高阶或不同类型的滤波器。 当然,零交叉点音高检测将天生受限,低通滤波器可能不足够。 更新:澄清了低通滤波器的目的是强调基频而不是消除噪声。

只有当基频是音符音高的最强谱成分时,低通滤波器才会起作用。对于许多乐器,包括钢琴,在许多音符上这并不成立。 - hotpaw2
实际上,那不是真的。只要基本频率存在,它就是最低音高,因此低通滤波器会增强基频相对于其他偏振分量的作用,这就是我建议使用它的原因。我将稍微编辑我的答案以使其更清晰明了。 - Bjorn Roche
1
@BjornRoche:实际上,那并不一定是真的!http://en.wikipedia.org/wiki/Subharmonic - Oliver Charlesworth
亚谐波是个例外。如果OP询问的是钢琴,那么这是一个合理的假设。 - Bjorn Roche

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