两个音频信号之间的时间延迟估计

14

我有两个不同麦克风(例如WAV格式)录制的同一信号的音频记录,但其中一个录制有延迟,例如数秒。

当在某种波形查看器中查看这些信号时,很容易通过视觉识别出这种延迟 - 即只需在每个信号中找到第一个可见峰,并确保它们具有相同的形状:


(来源: greycat.ru)

但是,如何以编程方式实现 - 找出这个延迟(t)是多少? 两个数字化信号略有不同(因为麦克风不同,位置不同,由于ADC设置等原因)。

我稍微搜索了一下,发现这个问题通常称为“时间延迟估计”,并且有无数的方法可以解决它 - 例如其中之一

但是否存在任何简单且现成的解决方案,例如命令行实用程序、库或直接的算法?

结论:我没有找到简单的实现方式,因此我自己做了一个简单的命令行工具 - 可在https://bitbucket.org/GreyCat/calc-sound-delay上获得(使用GPLv3许可)。它实现了一个非常简单的搜索最大值算法,该算法在Wikipedia上有描述。

3个回答

14
你所需要的技术称为交叉相关。它是一种非常简单但计算密集的技术,可用于解决各种问题,包括测量两个相似信号(信号不需要完全相同)之间的时间差(也称为滞后)。
如果你对滞后值有一个合理的想法(或者至少知道预期的滞后值范围),那么可以大大减少总计算量。同样,如果你能明确限制所需的精度,也可以做到如此。

是的,互相关,没错。如果能够估计出一个好的起始点,计算量可以减少。 - Dan
1
我四处搜寻,但没有找到这个算法的简单实现,所以我自己写了一个并发布在 https://bitbucket.org/GreyCat/calc-sound-delay 上。 - GreyCat
如果使用FFT,交叉相关会快得多。https://gist.github.com/376572 - endolith
卷积和交叉相关性的直觉:https://www.youtube.com/watch?v=MQm6ZP1F6ms - XMB5
这种技术能否用于声学信号? - Aniiya0978
@Aniiya0978:是的,音频信号是非常常见的用例。 - Paul R

2

我曾经遇到相同的问题,但没有找到一款自动同步视频/音频录制开始的工具,于是我决定开发 syncstart (github)。

这是一个命令行工具。它的基本代码如下:

import numpy as np
from scipy import fft
from scipy.io import wavfile
r1,s1 = wavfile.read(in1)
r2,s2 = wavfile.read(in2)
assert r1==r2, "syncstart normalizes using ffmpeg"
fs = r1
ls1 = len(s1)
ls2 = len(s2)
padsize = ls1+ls2+1
padsize = 2**(int(np.log(padsize)/np.log(2))+1)
s1pad = np.zeros(padsize)
s1pad[:ls1] = s1
s2pad = np.zeros(padsize)
s2pad[:ls2] = s2
corr = fft.ifft(fft.fft(s1pad)*np.conj(fft.fft(s2pad)))
ca = np.absolute(corr)
xmax = np.argmax(ca)
if xmax > padsize // 2:
    file,offset = in2,(padsize-xmax)/fs
else:
    file,offset = in1,xmax/fs

Roland,我正在测试您的代码,发现有一个错误。在最后一个if语句中,您调用了变量"in1或in2",但这些变量没有在任何地方定义。 - little_mice
那就是文件名。请参见GitHub版本 - Roland Puntaier

1
一个非常直接的做法就是检查峰值是否超过某个阈值,A线高峰和B线高峰之间的时间可能就是你的延迟。只需稍微调整一下阈值,如果图像通常像你发布的图片一样清晰,那么你应该没问题。

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