音频分析中的自相关


11

我正在阅读Autocorrelation,但是我不确定我确切地了解它是如何工作的以及应该期待的输出。我认为我应该将信号输入到交流功能并具有滑动窗口输入是正确的吗?每个窗口(例如,1024个样本)将输出一个介于-1和1之间的系数。该符号仅说明该线是向上还是向下,而值则说明相关程度。为了简单起见,可以说我没有重叠,只是每次将窗口移动1024个样本。在44100的样本中,我会得到43个系数,是否需要保留所有系数?

可以说我以200秒的信号执行此操作,得到8600个系数。我将如何使用这些系数来检测重复,进而检测速度?我应该创建某种神经网络来对它们进行分组,还是那太过分了?

谢谢你的帮助。


4
假设您的样本是x [ 1 ] x [ 2 ] x [ 1024 ]。您能告诉我们您的AC函数返回什么吗?可能的答案可能是:“它返回1024 i = 1x [ i ] 2 ”或“它返回1024个数字R [ k ],其中R [ k ] = 1024 k1024X[1个]X[2]X[1024]一世=1个1024X[一世]21024[R[ķ]”或“它返回1024个数字R[k],其中R[k]= 1024 k i = 1 x[i]x[i+k]+ k i = 1 x[1024k+i]xR[k]=i=11024kx[i]x[i+k]1024R[k]。”所有这三个参考答案与自相关的概念相兼容。R[k]=i=11024kx[i]x[i+k]+i=1kx[1024k+i]x[i]
迪利普Sarwate

嘿Dilip,谢谢您的帮助。我还没有实现AC功能,我只是想首先了解一下理论。第一个方程看起来最简单,但是是否需要事先对数据进行归一化?
XSL

1
这是一个示例:gist.github.com/255291#L62
endolith 2011年

Answers:


23

自相关的思想是提供给定滞后下信号与其自身之间相似度的度量。有几种方法可以解决此问题,但是出于音高/速度检测的目的,您可以将其视为搜索过程。换句话说,您逐步地逐个信号地进行信号,并在参考窗口和滞后窗口之间进行关联。“滞后0”处的相关将是全局最大值,因为您正在将引用与其自身的逐字副本进行比较。随着您的前进,相关性必定会降低,但是在周期性信号的情况下,在某个点它将逐渐增加,然后达到局部最大值。“滞后0”和第一个峰值之间的距离使您可以估计音调/速度。我的方式

在高采样率下,计算逐样本相关性可能在计算上非常昂贵,因此通常使用基于FFT的方法。进行感兴趣段的FFT,将其乘以其复共轭,然后进行逆FFT,将得到循环自相关。在代码中(使用numpy):

freqs = numpy.fft.rfft(signal)
autocorr = numpy.fft.irfft(freqs * numpy.conj(freqs))

相对于周期性分量(按照定义,它们与它们自身相似),其效果将是减少信号中的噪声(与自身不相关)的数量。在进行逆变换之前重复自相关(即共轭乘法)将进一步降低噪声。考虑正弦波与白噪声混合的示例。下图显示了440hz正弦波,被噪声“破坏”的相同正弦波,噪声波的循环自相关和双循环自相关:

自相关

请注意,两个自相关信号的第一个峰值如何恰好位于原始信号的第一个周期的末尾。那就是您要确定周期性(在这种情况下为音高)的峰值。第一个自相关信号仍然有点“摆动”,因此为了进行峰值检测,将需要某种平滑处理。在频域中两次自相关可以完成相同的事情(并且相对较快)。请注意,“摆动”是指放大时信号的外观,而不是出现在图中心的倾斜。循环自相关的后半部分将始终是前半部分的镜像,因此这种“浸入”是典型的。为了清楚了解算法,代码如下所示:

freqs = numpy.fft.rfft(signal)
auto1 = freqs * numpy.conj(freqs)
auto2 = auto1 * numpy.conj(auto1)
result = numpy.fft.irfft(auto2)

是否需要做多个自相关取决于信号中有多少噪声。

当然,这个想法有许多微妙的变化,在这里我将不做讨论。我所见过的最全面的内容(在音高检测方面)是Rabiner和Schafer编写的语音信号数字处理


现在,关于自相关是否足以进行速度检测。答案是肯定的。您可以获得一些速度信息(取决于源信号),但是在所有情况下都很难理解其含义。例如,这是一个breakbeat的两个循环的图,然后是整个序列的循环自相关的图:

差拍自相关

供参考,以下是相应的音频:

当然,在中间与循环点相对应的位置有一个不错的尖峰,但它来自处理相当长的一段。最重要的是,如果它不是一个精确的副本(例如,如果有仪器的话),那么尖峰将不那么干净。自相关在速度检测中绝对有用,但是对于复杂的源材料而言,自相关可能并不足够。例如,即使您发现尖峰,如何知道它是完整小节,四分音符,半音符还是其他?在这种情况下,很明显这是一个完整的衡量标准,但事实并非总是如此。我建议您在较简单的信号上使用交流电,直到内部工作情况变得清晰为止,然后再问另一个有关速度检测的问题(因为这是一个“更大”的问题)


2
等等,是音频信号本身的自相关吗?对于数字循环以外的速度检测,这当然不是很有用。通常,某些RMS包络的自相关应该更好地工作,最好分别用于多个频带。
左转

1
只要音乐有某种节拍,STFT在时间方向上的自相关就可以很好地发挥作用。这本质上与运行多个频带的自相关然后将它们求和在一起相同。
endlith 2011年

2
@leftroundabout正确,除了自身的自相关功能之外,还有许多其他事情需要进行速度检测(前置,后处理)。我主要回答OP的第一句话(即“自相关如何工作”),然后建议他问另一个有关速度检测的问题,因为将涉及其他过程。
datageist

@endolith在这里是Autocorrelation of the STFT in the time direction什么意思?特别是时间方向部分
popctrl

1
@popctrl的含义是计算STFT的每一行的自相关
内层石

3

听起来好像您想使用自相关来进行节拍检测。您可以执行此操作,但是我建议您对音频进行大幅下采样。您正在寻找1到3 Hz(60 bpm至180 bpm)之间的信号,因此不需要或不需要44100 Hz的分辨率。滞后0时,正确计算并归一化的自相关值为1.0(信号与其自身完全相关)。对于周期性信号,交流电下降到零以下,然后以对应于基频的滞后的峰值返回,而谐波处的峰值较小。您必须选择一个合理的范围来搜索此峰。对于噪声,自相关下降,并且在零附近的波形中基本上呈扁平状。根据经验,如果归一化交流中的峰值> 0.5,则您将获得一个周期性信号。


1

自相关只是信号与其自身的互相关。一种简单的计算方法是在原始信号和信号的时间翻转版本之间进行卷积。如果您的信号长度为1000个样本,则其自动相关将具有1999(2 * N-1)个非零样本。这些样本中只有1000个是唯一的,因为自动相关(对于真实信号)在时间上总是对称的,即ac [n] = ac [-n]。

连续信号需要分解成有限的部分。这类似于傅立叶变换:从技术上讲,您需要从-inf到+ inf进行集成,但将其分解为多个段(根据需要具有重叠和/或加窗)也可以产生有用的结果。窗口长度,形状和重叠的选择取决于应用程序。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.