在JavaScript中比较音源和麦克风之间的声音

1 javascript audio microphone audio-fingerprinting

我正在研究音频,但是我是该领域的新手。我想将来自麦克风的声音与源音频(仅1种声音)进行匹配,例如Shazam的可乐广告。示例视频(0.45分钟)但是,我想通过JavaScript在网站上制作。谢谢。

rp.*_*ran 6

构建类似于Shazam后端的内容并非易事。我们要:

  1. 从用户的麦克风获取音频(简单)
  2. 将其与源进行比较,并确定匹配项(嗯...怎么做...)

我们如何执行每个步骤?

获取音频

这绝对是不容置疑的。我们可以Web Audio API为此使用。您可以在Google周围搜索有关如何使用它的良好教程。该链接提供了一些您可能在使用时可能需要了解的基础知识。

比较样本与音频源文件

显然,在这样的项目中,这将是算法挑战。可能有很多种方法来处理此部分,并且在这里没有足够的时间来描述它们,但是一种可行的技术(恰好是Shazam实际使用的方法)(在此处也进行了详细说明)是创建和比较相对于较小的原始材料指纹,您可以使用FFT分析生成指纹。

其工作原理如下:

  1. 一次查看不超过几秒钟的样本中的小部分(请注意,这是使用滑动窗口完成的,而不是离散分区)
  2. 计算音频选择的傅立叶变换。这将我们的选择分解为许多不同频率的信号。我们可以分析样本的频域,以得出关于所听到声音的有用结论。
  3. 通过识别FFT中的关键值(例如峰值频率或幅度)来创建用于选择的指纹
  4. 如果您希望能够像Shazam一样匹配多个样本,则应该维护一个指纹词典,但是由于您只需要匹配一个原始资料,因此可以将它们保存在一个列表中。由于您的键将是一个数值数组,因此我建议另一个可以快速查询数据集的数据结构是kd tree。我不认为Shazam使用一个,但是我想得越多,如果可以保持关键点的数量一致,他们的系统就越接近n维最近邻搜索。不过,暂时保持简单,使用列表。

现在,我们有了一个已准备好使用的指纹数据库。现在,我们需要将它们与我们的麦克风输入进行比较。

  1. 以与我们的信号源相同的方式,在带有滑动窗口的小段中采样我们的麦克风输入。
  2. 对于每个段,计算指纹,然后查看它是否与存储中的任何一个匹配。您可以在此处查找部分匹配项,并且可以尝试许多调整和优化。
  3. 这将是一个嘈杂且不准确的信号,因此不要指望每个片段都能得到匹配。如果其中有很多人匹配(您必须通过实验弄清楚很多意味着什么),则假设您有一个。如果比赛相对较少,那么就算你没有。

结论

要做好,这将不是一个超级容易的项目。所需的调整和优化量将证明是一个挑战。某些麦克风不准确,大多数环境还带有其他声音,所有这些都会干扰您的结果,但可能还不如听起来那么糟糕。我的意思是,从外部看,这是一个非常复杂的系统,我们只是将其分解为一些相对简单的步骤。

最后,您在帖子中多次提到Javascript,您可能会注意到到目前为止,我在答案中提到Java的次数为零,这是因为实现语言不是重要因素。这个系统非常复杂,难题中最难解决的部分将是您在纸上解决的部分,因此您无需考虑“我如何在Y中做X”,只需找出一种算法即可X,而Y应该自然而然地出现。