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

Dom*_*Ong 5 c# algorithm audio comparison spectrogram

我每天录制2分钟的互联网广播。总是有相同的开始和结束叮当声。由于广播的确切时间可能会有所不同,大约需要6分钟,因此我必须录制大约15分钟的广播。

我希望确定15分钟录音中这些杂音的确切时间,以便提取所需的音频部分。

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

我尝试在PCM数据上使用互相关算法,但是该算法在6分钟左右的过程中非常慢,步长为10ms,并且在某些情况下无法找到叮当声的开始时间。

对两个频谱图进行匹配比较的算法有什么想法吗?还是找到铃声开始时间的更好方法?

谢谢,

更新,抱歉造成延迟

首先,感谢所有的答案,其中大多数都是无关紧要的想法。

我尝试实现fonzo提出的Shazam算法。但是未能检测到光谱图中的峰。这是来自三个不同记录的起始铃声的三个频谱图。我尝试使用带有斑点过滤器的AForge.NET(但未能识别峰值),模糊图像并检查高度差,拉普拉斯卷积,斜率分析以检测一系列竖线(但错误太多)正)...

同时,我尝试了Dave Aaron Smith提出的Hough算法。我在哪里计算每列的RMS。是是每一列都是O(N * M),但是M << N(注意,一列大约是8k的样本)。因此,总的来说还算不错,该算法大约需要3分钟,但绝不会失败。

我可以采用该解决方案,但如果可能的话,我希望使用Shazam,因为它的O(N)可能更快(并且也更凉爽)。大家都想出一种算法,可以始终检测那些频谱图中的相同点(不必是峰值),这要感谢添加注释。

FFT开始叮当1

FFT开始丁当2

FFT开始丁当3

新更新

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

谢谢你的帮助。

Dav*_*ith 2

我想知道你是否可以使用霍夫变换。您将首先对开头序列的每个步骤进行编目。假设您使用 10 毫秒的步长,并且打开序列的长度为 50 毫秒。您在每个步骤上计算一些指标并得到

1 10 1 17 5
Run Code Online (Sandbox Code Playgroud)

现在检查您的音频并分析每个 10 毫秒步骤的相同指标。调用这个数组have_audio

8 10 8 7 5 1 10 1 17 6 2 10...
Run Code Online (Sandbox Code Playgroud)

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

所以对于这个例子have_audio,你的votes意愿看起来像

2 0 0 1 0 4 0 0 0 0 0 1 ...
Run Code Online (Sandbox Code Playgroud)

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

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

  • 你好,谢谢你的回复,今天我学到了一些东西。但我真的不知道可以使用什么度量来表示信号的一部分。频谱图是一个数组,我可以针对不同频率(例如 100)运行此算法,并对每个部分的投票进行求和。不过我对表演感到好奇。 (2认同)