使用 FFT 匹配两个音频文件 (Android Studio)
Matching two audio files using FFT (Android Studio)
过去几天我一直在开发我的应用程序的一部分,我需要同时播放和录制音频文件。我需要完成的任务只是比较录音与播放的音频文件和 return 匹配百分比。这是我到目前为止所做的以及我的问题的一些背景信息:
目标API>15
我决定使用 .wav 音频文件格式来简化文件解码
- 我使用 AudioRecord 进行录音,使用 MediaPlayer 播放音频文件
- 我创建了一个决策程序 class 以传递我的音频文件并将其转换为 PCM 以执行匹配分析
- 我正在使用以下规格的录音音频格式(CHANNEL_MONO、16 位、SAMPLE_RATE = 44100)
- 将音频文件传递给解码器后,我继续将其传递给 FFT class 以获得分析所需的频域数据。
下面是我的几个问题:
- 当我使用 AudioRecord 录制音频时,默认格式是 PCM 还是我需要如何指定?
- 我正在尝试将记录传递给 FFT class 以获取频域数据来执行我的匹配分析。有没有办法在不将录音保存在用户设备上的情况下执行此操作?
- 对两个文件进行FFT分析后,是否需要将数据存储在文本文件中,以便进行匹配分析?有哪些选择或可行的方法可以做到这一点?
- 经过大量研究,我找到的所有资源都涵盖了如何将录音与数据库中包含的 song/music 相匹配。我的目标是查看两个特定音频文件的匹配程度,我该怎么做? - 我是否需要 create/use 哈希函数才能实现我的目标?对此的详细回答将非常有帮助
- 目前我有一个单独的线程用于记录;单独 activity 用于解码音频文件;单独 activity 用于 FFT 分析。我计划 运行 在单独的线程或 AsyncTask 中进行匹配分析。您认为这种结构是最优的还是有更好的方法?另外,我是否也应该在单独的线程中将音频文件传递给解码器,还是可以在录音线程或 MatchingAnalysis 线程中进行?
- 我对音频文件的操作是否需要加窗才能进行匹配比较?
- 我需要解码 .wav 文件还是可以直接比较 2 个 .wav 文件?
- 比对前是否需要对音频文件进行低音操作?
- 为了进行匹配比较,我到底需要生成哪些数据(功率谱、能谱、频谱图等)?
我这样做的方式是否正确,还是我遗漏了什么?
在像 Shazam 这样的应用程序中,Midomi 音频匹配是使用称为 audio-fingerprinting 的技术完成的,该技术使用频谱图和散列法。
- 你找到 FFT 的第一步是正确的,但是你需要在时间和频率之间制作一个称为频谱图的二维图。
- 此频谱图数组包含超过百万个样本,我们无法处理这么多数据。所以我们找到了振幅的峰值。峰值将是一个(时间,频率)对,对应于在其周围 局部邻域 中最大的振幅值。峰值查找将是一个计算成本很高的过程,不同的应用程序或项目以不同的方式执行此操作。我们使用峰值是因为它们对背景噪音更不敏感。
- 现在不同的歌曲可以有相同的峰值,但不同的是出现的顺序和时间的不同。所以我们将这些峰值组合成唯一的哈希值并将它们保存在数据库中。
- 对您希望应用识别并从数据库中匹配的每个音频文件执行上述过程。虽然匹配并不简单,但也要考虑时间差,因为歌曲可以来自任何时刻,而且我们有完整歌曲的指纹。但这不是问题,因为指纹包含相对时间差。
这个过程比较详细,您可以在此 link http://www.ee.columbia.edu/~dpwe/papers/Wang03-shazam.pdf
中找到更多解释
有些库可以为您完成 dejavu (https://github.com/worldveil/dejavu) 和 chromaprint(在 c++ 中)。 google 的 Musicg 在 java 中,但它在背景噪音下表现不佳。
匹配两个音频文件是一个复杂的过程,和上面的评论一样,我也会告诉你先在PC上试,然后在手机上试。
过去几天我一直在开发我的应用程序的一部分,我需要同时播放和录制音频文件。我需要完成的任务只是比较录音与播放的音频文件和 return 匹配百分比。这是我到目前为止所做的以及我的问题的一些背景信息:
目标API>15
我决定使用 .wav 音频文件格式来简化文件解码
- 我使用 AudioRecord 进行录音,使用 MediaPlayer 播放音频文件
- 我创建了一个决策程序 class 以传递我的音频文件并将其转换为 PCM 以执行匹配分析
- 我正在使用以下规格的录音音频格式(CHANNEL_MONO、16 位、SAMPLE_RATE = 44100)
- 将音频文件传递给解码器后,我继续将其传递给 FFT class 以获得分析所需的频域数据。
下面是我的几个问题:
- 当我使用 AudioRecord 录制音频时,默认格式是 PCM 还是我需要如何指定?
- 我正在尝试将记录传递给 FFT class 以获取频域数据来执行我的匹配分析。有没有办法在不将录音保存在用户设备上的情况下执行此操作?
- 对两个文件进行FFT分析后,是否需要将数据存储在文本文件中,以便进行匹配分析?有哪些选择或可行的方法可以做到这一点?
- 经过大量研究,我找到的所有资源都涵盖了如何将录音与数据库中包含的 song/music 相匹配。我的目标是查看两个特定音频文件的匹配程度,我该怎么做? - 我是否需要 create/use 哈希函数才能实现我的目标?对此的详细回答将非常有帮助
- 目前我有一个单独的线程用于记录;单独 activity 用于解码音频文件;单独 activity 用于 FFT 分析。我计划 运行 在单独的线程或 AsyncTask 中进行匹配分析。您认为这种结构是最优的还是有更好的方法?另外,我是否也应该在单独的线程中将音频文件传递给解码器,还是可以在录音线程或 MatchingAnalysis 线程中进行?
- 我对音频文件的操作是否需要加窗才能进行匹配比较?
- 我需要解码 .wav 文件还是可以直接比较 2 个 .wav 文件?
- 比对前是否需要对音频文件进行低音操作?
- 为了进行匹配比较,我到底需要生成哪些数据(功率谱、能谱、频谱图等)?
我这样做的方式是否正确,还是我遗漏了什么?
在像 Shazam 这样的应用程序中,Midomi 音频匹配是使用称为 audio-fingerprinting 的技术完成的,该技术使用频谱图和散列法。
- 你找到 FFT 的第一步是正确的,但是你需要在时间和频率之间制作一个称为频谱图的二维图。
- 此频谱图数组包含超过百万个样本,我们无法处理这么多数据。所以我们找到了振幅的峰值。峰值将是一个(时间,频率)对,对应于在其周围 局部邻域 中最大的振幅值。峰值查找将是一个计算成本很高的过程,不同的应用程序或项目以不同的方式执行此操作。我们使用峰值是因为它们对背景噪音更不敏感。
- 现在不同的歌曲可以有相同的峰值,但不同的是出现的顺序和时间的不同。所以我们将这些峰值组合成唯一的哈希值并将它们保存在数据库中。
- 对您希望应用识别并从数据库中匹配的每个音频文件执行上述过程。虽然匹配并不简单,但也要考虑时间差,因为歌曲可以来自任何时刻,而且我们有完整歌曲的指纹。但这不是问题,因为指纹包含相对时间差。
这个过程比较详细,您可以在此 link http://www.ee.columbia.edu/~dpwe/papers/Wang03-shazam.pdf
中找到更多解释有些库可以为您完成 dejavu (https://github.com/worldveil/dejavu) 和 chromaprint(在 c++ 中)。 google 的 Musicg 在 java 中,但它在背景噪音下表现不佳。
匹配两个音频文件是一个复杂的过程,和上面的评论一样,我也会告诉你先在PC上试,然后在手机上试。