使用FFT匹配两个音频文件(Android Studio)

时间:2017-01-04 04:47:48

标签: java android android-studio audio audio-fingerprinting

过去几天我一直在处理我的应用程序的一部分,我需要同时播放和录制音频文件。我需要完成的任务只是将录音与播放的音频文件进行比较并返回匹配的百分比。这是我到目前为止所做的以及我的问题的一些背景:

  • 目标API>> 15

  • 我决定使用.wav音频文件格式来简化文件解码

  • 我正在使用AudioRecord进行录制,使用MediaPlayer播放音频文件
  • 我创建了一个decider类,以传递我的音频文件并将其转换为PCM以执行匹配分析
  • 我正在使用以下规格录制AudioFormat(CHANNEL_MONO,16 BIT,SAMPLE_RATE = 44100)
  • 将音频文件传递给解码器后,我继续将其传递给FFT类,以获取分析所需的频域数据。

以下是我的一些问题:

  • 当我使用AudioRecord录制音频时,默认情况下是格式PCM还是我需要指定一些如何?
  • 我正在尝试将录音传递给FFT类,以便获取频域数据以执行我的匹配分析。有没有办法在不保存用户设备上的录音的情况下执行此操作?
  • 对两个文件执行FFT分析后,是否需要将数据存储在文本文件中才能执行匹配分析?有哪些选择或可能的方法来做到这一点?
  • 经过大量研究后,我发现的所有资料都涵盖了如何将录音与数据库中包含的歌曲/音乐相匹配。我的目标是看看两个特定音频文件的匹配程度,我将如何进行此操作? - 我是否需要创建/使用哈希函数才能实现目标?对此的详细解答将非常有帮助
  • 目前我有一个单独的录音线程;用于解码音频文件的单独活动;用于FFT分析的单独活动。我打算在一个单独的线程或AsyncTask中运行匹配分析。你认为这种结构是最优的还是有更好的方法呢?另外,我是否应该在单独的线程中将音频文件传递给解码器,还是可以在录制线程或MatchingAnalysis线程中执行?
  • 在进行匹配比较之前,是否需要在音频文件操作中执行窗口化?
  • 我是否需要解码.wav文件,或者我可以直接比较2 .wav文件?
  • 在比较之前,我是否需要对音频文件执行低音调操作?
  • 为了进行匹配比较,我需要生成哪些数据(功率谱,能谱,谱图等)?

我是以正确的方式解决这个问题还是我错过了什么?

1 个答案:

答案 0 :(得分:1)

在像Shazam这样的应用中,Midomi音频匹配是使用称为音频指纹的技术完成的,该技术使用频谱图和散列。

  • 找到FFT的第一步是正确的,但是你需要在时间和频率之间制作一个名为Spectrogram的二维图。
  • 此光谱图阵列包含超过百万个样本,我们无法处理这么多数据。所以我们发现振幅达到峰值。峰值将是对应于幅度值的(时间,频率)对,该幅度值在其周围的局部邻域中最大。高峰发现将是一个计算成本高昂的过程,不同的应用程序或项目以不同的方式执行此操作。我们使用峰值,因为它们会对背景噪声更不敏感。
  • 现在不同的歌曲可以有相同的峰值,但差异将是顺序和发生的时间差异。因此,我们将这些峰值组合成唯一的哈希值并将其保存在数据库中。
  • 对您希望应用识别的每个音频文件执行上述过程,并将其与您的数据库进行匹配。虽然匹配不简单,但也应该考虑时差,因为歌曲可以来自任何瞬间,并且我们有完整歌曲的指纹。但这不是问题,因为指纹包含相对时差。

这是一个有点详细的过程,您可以在此链接中找到更多解释http://www.ee.columbia.edu/~dpwe/papers/Wang03-shazam.pdf

有些库可以为你做dejavu(https://github.com/worldveil/dejavu)和chromaprint(用c ++编写)。谷歌的Musicg是在java中,但它在背景噪音方面表现不佳。

匹配两个音频文件是一个复杂的过程,就像上面的评论一样,我也会告诉你先在电脑上试用,然后在手机上试试。