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

时间:2017-08-20 17:56:45

标签: javascript audio microphone audio-fingerprinting

我正在处理音频,但我是这个领域的新手。我想将来自麦克风的声音与我的源音频(只有1个声音)匹配,就像来自Shazam的可乐广告一样。 Example Video(0.45分钟)但是,我想通过JavaScript在网站上制作它。谢谢。

1 个答案:

答案 0 :(得分:4)

构建类似于Shazam后端的东西并非易事。我们需要:

  1. 从用户的麦克风中获取音频(简单)
  2. 将其与来源进行比较并确定匹配(嗯......怎么做......)
  3. 我们如何执行每一步?

    Aquire Audio

    这个绝对没有大事。我们可以使用Web Audio API来实现此目的。你可以谷歌周围的关于如何使用它的好教程。 This link提供了一些您在使用时可能想要了解的基本知识。

    将样本与音频源文件进行比较

    显然,这件作品将成为像这样的项目中的算法挑战。可能有各种方法来处理这一部分,而没有足够的时间在这里描述它们,但是一种可行的技术(恰好是Shazam实际使用的技术),以及更详细地描述here,创建和比较源材料的较小部分的指纹,您可以使用FFT分析生成。

    其工作原理如下:

    1. 一次查看样本的小部分不超过几秒钟(请注意,这是使用滑动窗口完成,而不是使用离散分区)
    2. 计算音频选择的傅里叶变换。这将我们的选择分解为许多不同频率的信号。我们可以分析样本的频域,以得出关于我们听到的有用的结论。
    3. 通过识别FFT中的关键值(例如峰值频率或幅度
    4. )为选择创建指纹
    5. 如果你想能够像Shazam那样匹配多个样本,你应该保留一个指纹字典,但由于你只需要匹配一个源材料,你可以将它们保存在一个列表中。由于您的密钥将是一个数值数组,我建议另一个可能快速查询数据集的数据结构是k-d tree。我不认为Shazam使用一个,但是我想的越多,他们的系统似乎越接近n维最近邻搜索,如果你可以保持临界点的数量一致。但就目前而言,只需保持简单,请使用清单。
    6. 现在我们有一个已准备好使用的指纹数据库。我们现在需要将它们与我们的麦克风输入进行比较。

      1. 使用滑动窗口以小段示例我们的麦克风输入,就像我们的来源一样。
      2. 对于每个细分,计算指纹,并查看它是否与存储中的任何一个接近。你可以在这里寻找部分匹配,你可以尝试很多调整和优化。
      3. 这将是一个嘈杂且不准确的信号,因此不要指望每个段都能获得匹配。如果他们中的很多人得到了一个匹配(你将不得不弄清楚实际上的批次意味着什么),那么假设你有一个。如果比赛相对较少,那么请注意不要。
      4. 结论

        这不是一个非常容易做得好的项目。所需的调整和优化量将证明是一项挑战。有些麦克风不准确,大多数环境都有其他声音,所有这些都会使你的结果变得混乱,但它也可能没有声音那么糟糕。我的意思是,这是一个从外部看起来非常复杂的系统,我们只是把它分解成一些相对简单的步骤。

        另外作为最后一点,你在帖子中多次提到Javascript,你可能会注意到我在答案中提到过零次,这是因为实施语言不是一个重要因素。这个系统足够复杂,最难解决的问题就是你在纸上解决的问题,所以你不需要考虑“如何在Y中做X”,只需找出一个算法X,Y应该自然而然。