比较两个频谱图,找到匹配算法的偏移量

时间:2011-04-13 15:26:19

标签: c# algorithm audio comparison spectrogram

我每天从互联网上录制2分钟的电台广播。始终有相同的开始和结束的叮当声。由于无线电广播的准确时间可能差不多或多于6分钟,我必须录制约15分钟的收音机。

我想确定这些歌曲在15分钟录音中的确切时间,因此我可以提取我想要的音频部分。

我已经启动了一个C#应用程序,我将MP3解码为PCM数据并将PCM数据转换为基于http://www.codeproject.com/KB/audio-video/SoundCatcher.aspx

的频谱图

我尝试在PCM数据上使用交叉相关算法,但算法在6分钟内非常慢,步长为10ms,有时无法找到叮当开始时间。

比较两个谱图匹配算法的任何想法?还是找到叮当开始时间的更好方法?

谢谢,

更新,抱歉延迟

首先,感谢所有的主人,他们中的大多数都是相关的或有趣的想法。

我试图实现fonzo提出的Shazam算法。但未能检测到频谱图中的峰值。这是来自三个不同记录的起始叮当的三个频谱图。我尝试了AForge.NET的blob滤镜(但它无法识别峰值),模糊图像并检查高度差异,拉普拉斯卷积,斜率分析,以检测一系列垂直条(但是有太多的错误正)...

同时,我尝试了Dave Aaron Smith提出的Hough算法。我在哪里计算每列的RMS。是的是每列,它是O(N * M)但是M <&lt;&lt; N(注意一列是大约8k的样本)。所以总体而言并不是那么糟糕,算法大约需要3分钟,但从未失败过。

我可以选择那个解决方案,但如果可能的话,我更喜欢Shazam因为它是O(N)并且可能更快(也更冷)。因此,你们中的任何一个人都知道一种算法可以始终检测这些光谱图中的相同点(不一定是峰值),这要归功于添加注释。

FFT Start Jingle 1

FFT Start Jingle 2

FFT Start Jingle 3

新更新

最后,我使用上面解释的算法,我尝试实现Shazam算法,但未能在频谱图中找到适当的峰值,从一个声音文件到另一个声音文件不一致的识别点。理论上,Shazam算法是解决这类问题的方法。 Dave Aaron Smith提出的Hough算法更稳定有效。我分割了大约400个文件,其中只有20个未能正确分割。磁盘空间从8GB到1GB。

谢谢你的帮助。

4 个答案:

答案 0 :(得分:4)

这里有一个shazam服务使用的算法的描述(它可以识别一个可能有噪音的短音乐):http://www.ee.columbia.edu/~dpwe/papers/Wang03-shazam.pdf
根据我的理解,首先要做的是隔离频谱图中的峰值(通过一些调整以确保均匀覆盖),这将给出来自初始频谱图的一对值(时间;频率)的“星座”。完成后,通过将样本长度的窗口从开头到结尾进行转换并计算相关点的数量,将样本星座与完整轨道的星座进行比较。
然后,本文描述了他们发现的技术解决方案,即使对于大量的音轨也能够快速进行比较。

答案 1 :(得分:2)

我想知道你是否可以使用Hough transform。您首先要对开始序列的每个步骤进行编目。假设您使用10 ms步长,开启序列长度为50 ms。您计算每个步骤的一些指标并获得

1 10 1 17 5

现在浏览您的音频并分析相同指标的每个10 ms步骤。调用此数组have_audio

8 10 8 7 5 1 10 1 17 6 2 10...

现在创建一个与have_audio长度相同的新空数组。称之为start_votes。它将包含开始序列开始的“投票”。如果您看到1,则您可能处于开始序列的第1或第3步,因此您对1步前开始的开场序列有1票,对3开始前的开场序列有1票。如果你看到一个10,那么你对1步之前的开场序列有1票,对4步之前有17票,依此类推。

因此对于该示例have_audio,您的votes看起来像

2 0 0 1 0 4 0 0 0 0 0 1 ...

你在第6位有很多选票,所以开场顺序很可能从那里开始。

您可以通过不打算分析整个开场序列来提高性能。如果打开序列长达10秒,您可以搜索前5秒。

答案 2 :(得分:2)

这是一个很好的python包,可以做到这一点:

https://code.google.com/p/py-astm/

如果您正在寻找特定的算法,那么使用的好搜索术语是“accoustic fingerprinting”或“感知哈希”。

这是另一个也可以使用的python包:

http://rudd-o.com/new-projects/python-audioprocessing/documentation/manuals/algorithms/butterscotch-signatures

答案 3 :(得分:1)

如果你已经知道了叮当序列,你可以分析与序列的相关性,而不是整个15分钟轨道之间的互相关。

为了快速计算与(短)序列的相关性,我建议使用Wiener filter

编辑:维纳滤波器是一种在具有噪声的序列中定位信号的方法。在这个应用程序中,我们正在考虑任何“不是叮当”的噪音(对于读者来说问题:我们仍然可以假设噪音是白色的并且没有相关性吗?)。

我找到了我正在寻找的参考!我记得的公式有点偏,我现在将它们删除

相关页面为Wiener deconvolution。我们的想法是,我们可以定义一个系统,其脉冲响应h(t)具有与叮当相同的波形,我们必须在系统已经接收到脉冲的嘈杂序列中定位该点(即:发出一个jingje)

由于叮当声是已知的,我们可以计算其功率谱H(f),因为我们可以假设在记录的序列中出现单个叮当声,我们可以说未知输入x(t)具有脉冲的形状,其功率密度S(f)在每个频率处是恒定的。

鉴于上述知识,你可以使用公式来获得一个“jingle-pass”过滤器(如同只有叮当声的信号可以通过),当播放铃声时输出最高。