2

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

  • 目标 API >15

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

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

以下是我的几个问题:

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

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

4

1 回答 1

2

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

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

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

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

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

于 2017-02-10T01:26:03.030 回答