比较wav文件

时间:2010-12-01 08:32:48

标签: java audio fft

我有一个(大多数)工作程序来比较两个wav文件,看看较小的文件是否在较大的文件中。这是在java。

中完成的

我首先确保两个wav文件都是规范波形格式。然后,我使用AudioInputStream从中获取数据的字节数组。我以特定帧速率的块(例如现在:4096字节)取出数据。我取较小输入的第一个块,并在较大的输入中浏览相同大小的块。

我采用这些块并使用相同的数据创建双数组。我得到他们的FFT并使用相关函数在得到的相关系数数组中找到一个峰值。然后我转到较小输入的下一个块,看看是否出现类似的峰值。

这样可行,当文件相同时峰值很明显,并且大多数时候结果都是正确的。我不会得到误报。但是,我会得到假阴性。

这是因为我不确定如何“对齐”数据。较小的文件可能来自较大文件中的任何一点。大多数情况下,这是通过我这样做的分块方法捕获的。但有时,就好像文件不同,并且没有找到峰值,尽管文件应该返回高相关性。

如果我把其中一个假阴性(没有峰值)的文件,并稍微调整一下,在它们的末尾或开始几千字节,并再次运行程序,它会突然发现峰值,这是一个非常明确的匹配。因此,它确实有效,它只是在某种程度上找不到相关性明显的峰值。相关函数我已经将FFT转换为匹配,所以我认为这将涵盖所有内容,但显然我没有覆盖所有数据。

我不确定如何将较小文件的块“对齐”到较大文件中的任何位置,以便相关函数选择相关发生的位置。一切正常,我只需消除假阴性。有什么建议吗?

4 个答案:

答案 0 :(得分:2)

使用卷积滤波器比较两个波形。它会告诉您匹配是否发生以及发生在何处。计算卷积的快速算法是available

答案 1 :(得分:2)

这称为matched filter。由于分块,您的实施正在受到影响。传统上,您将输入作为连续流,从每个样本开始提取块,并进行关联。因此,如果您的输入长度为10k样本,则最终运行过滤器10k次,每次将4k样本带入过滤器(在您的示例中)。但是,这很慢。有几种方法可以加快速度:

  1. 使用小块(如256点)来加快FFT计算速度。你的相关性可能看起来不那么好,导致更多的误报,但也许你可以列出可能的匹配,然后回头看看更大的块。

  2. 不是从输入中的每个样本开始缓冲,而是从每第512个样本开始取4k缓冲,比如说,并进行相关(类似于Marcelo Cantos's suggestion in his comment)。然后,寻找内部的峰值中间的512个样本,因为时移会导致尖峰移位。此外,边缘处的额外非相关样本将导致峰值不是全值,因此如果峰值不满,则需要放宽该约束。你有它。再次,这可能会导致更多的误报,所以你再次不得不求助于列表方法。

  3. 在实现细节方面,我假设您已经预先计算了较小文件中的块?此外,您没有说明是否检查时域或频域中的相关性。您可以在频域中查找平坦幅度,这相当于时域中的尖峰,以节省逆FFT。你需要做一些实验来确定频谱的平坦程度,但这可能会缩短时间。

答案 2 :(得分:0)

我不确定我是否完全掌握了你正在使用的算法,但是这里有一个想法:如果你可以通过在开头和结尾手动剪掉比特来识别波浪,那么这不是一个可能的解决方案。算法呢?

答案 3 :(得分:0)

您可以查看this paper。它解释了shazam服务使用的算法,该算法从几秒钟的样本中识别音乐 另一种方法here,使用自组织映射来聚类相似的音乐。不完全是你想要做的,但它可以给你一些想法。