Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用FFT匹配两个音频文件(Android Studio)_Java_Android_Android Studio_Audio_Audio Fingerprinting - Fatal编程技术网

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

Java 使用FFT匹配两个音频文件(Android Studio),java,android,android-studio,audio,audio-fingerprinting,Java,Android,Android Studio,Audio,Audio Fingerprinting,在过去的几天里,我一直在开发我的应用程序的一部分,我需要同时播放和录制一个音频文件。我需要完成的任务就是将录音与播放的音频文件进行比较,并返回匹配的百分比。以下是我迄今为止所做的工作以及我的问题的一些背景: 目标API>15 我决定使用.wav音频文件格式来简化对文件的解码 我使用AudioRecord进行录音,使用MediaPlayer播放音频文件 我创建了一个decider类,以便传递我的音频文件并将其转换为PCM,以便执行匹配分析 我使用以下规格的录音音频格式(单声道,16位,采样率=4

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

  • 目标API>15

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

  • 我使用AudioRecord进行录音,使用MediaPlayer播放音频文件
  • 我创建了一个decider类,以便传递我的音频文件并将其转换为PCM,以便执行匹配分析
  • 我使用以下规格的录音音频格式(单声道,16位,采样率=44100)
  • 在我将音频文件传递给解码器之后,我接着将其传递给FFT类,以便获得分析所需的频域数据
以下是我的几个问题:

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

我这样做是正确的还是遗漏了什么?

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

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

dejavu()和chromaprint(在c++中)有一些库可以为您完成这项工作。谷歌的Musicg是用java编写的,但它在背景噪音下表现不佳


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

您的听力太差了。在您考虑在移动设备上执行此操作之前,您需要开发一种算法,该算法可以在桌面计算机上运行时,将两个wave文件交给您,从而完成出色的工作。例如,考虑如何处理两个相同的文件(在真实世界中,你永远找不到,只是为了争论的缘故),它们只在一个未知的延迟中不同。你最好相信Android音频堆栈插入延迟!现在考虑延迟、噪声和不同频率响应的组合。现在添加房间回声…@ChrisStratton我想延迟可以通过添加滑动窗口或修剪/截断两个信号来解决,以便它们的持续时间匹配,对吗?或者使用散列函数可以让我们忽略时间延迟?收集一组测试数据记录,编写一些算法,想出一种给它们打分的方法。除了使用它进行数据采集(手机话筒不同于电脑话筒),在测试环境中取得良好结果之前,甚至不要触摸移动设备。@ChrisStratton我假设我正在使用手机录制音频并将其保存为.wav文件?在我完成你所说的之后,那又怎么样?@ChrisStratton,我该如何为他们得分呢?我应该使用能谱密度来评分吗?