使用卷积在连续的声音流中查找参考音频样本

在我之前关于在更大的音频样本中找到参考音频样本的问题中,有人建议我应该使用卷积。
使用DSPUtil ,我能够做到这一点。 我玩了一下,尝试了不同的音频样本组合,看看结果是什么。 为了可视化数据,我只是将原始音频作为数字转储到Excel并使用这些数字创建了一个图表。 一个高峰可见的,但我真的不知道这对我有什么帮助。 我有这些问题:

  • 我不知道,如何从峰值位置推断原始音频样本中匹配的起始位置。
  • 我不知道,我应该如何应用连续的音频流,所以一旦参考音频采样发生,我就能做出反应。
  • 我不明白,为什么图片2和图片4(见下文)差别如此之大,尽管两者都代表了与自身卷积的音频样本……

任何帮助都非常感谢。

以下图片是使用Excel进行分析的结果:

  1. 一个较长的音频样本,附近有参考音频(哔哔声): http : //img801.imageshack.us/img801/976/values1.png
  2. 哔哔声与自己融为一体: http : //img96.imageshack.us/img96/6720/values2i.png
  3. 没有哔哔声的较长音频样本与哔哔声融为一体: http : //img845.imageshack.us/img845/1091/values3.png
  4. 第3点的较长音频样本与其自身融合: http : //img38.imageshack.us/img38/1272/values4.png

更新和解决方案:
感谢Han的广泛帮助,我实现了我的目标。
在我没有FFT的情况下完成了自己的慢速实现之后,我发现alglib提供了快速实现。 我的问题有一个基本假设:其中一个音频样本完全包含在另一个中。
因此,以下代码返回两个音频样本中较大者中的样本中的偏移量以及该偏移量处的归一化互相关值。 1表示完全相关,0表示根本不相关,-1表示完全负相关:

private void CalcCrossCorrelation(IEnumerable data1, IEnumerable data2, out int offset, out double maximumNormalizedCrossCorrelation) { var data1Array = data1.ToArray(); var data2Array = data2.ToArray(); double[] result; alglib.corrr1d(data1Array, data1Array.Length, data2Array, data2Array.Length, out result); var max = double.MinValue; var index = 0; var i = 0; // Find the maximum cross correlation value and its index foreach (var d in result) { if (d > max) { index = i; max = d; } ++i; } // if the index is bigger than the length of the first array, it has to be // interpreted as a negative index if (index >= data1Array.Length) { index *= -1; } var matchingData1 = data1; var matchingData2 = data2; var biggerSequenceCount = Math.Max(data1Array.Length, data2Array.Length); var smallerSequenceCount = Math.Min(data1Array.Length, data2Array.Length); offset = index; if (index > 0) matchingData1 = data1.Skip(offset).Take(smallerSequenceCount).ToList(); else if (index  (x - mx) * (x - mx))); var denom2 = Math.Sqrt(matchingData2.Sum(y => (y - my) * (y - my))); maximumNormalizedCrossCorrelation = max / (denom1 * denom2); } 

BOUNTY:
无需新答案! 我开始赏金给Han,因为他继续努力解决这个问题!

在这里,我们去赏金:)

要在较大的音频片段中查找特定参考信号,您需要使用互相关算法。 基本公式可以在这篇维基百科文章中找到。

互相关是比较2个信号的过程。 这是通过将两个信号相乘并对所有样本的结果求和来完成的。 然后移动其中一个信号(通常是1个样本),并重复计算。 如果您尝试将此信息显示为非常简单的信号(例如单个脉冲(例如,1个样本具有特定值而其余样本为零)或纯正弦波,您将看到互相关的结果确实如此衡量两种信号的相似程度以及它们之间的延迟。 可以在此处找到可提供更多见解的另一篇文章。

Paul Bourke撰写的这篇文章还包含了简单的时域实现的源代码。 请注意,该文章是为一般信号而编写的。 音频具有特殊属性,即长时间平均值通常为0.这意味着保罗伯克公式(mx和my)中使用的平均值可以省略。 还有基于FFT的互相关的快速实现(参见ALGLIB )。

相关的(最大)值取决于音频信号中的样本值。 然而,在Paul Bourke的算法中,最大值被缩放到1.0。 在其中一个信号完全包含在另一个信号中的情况下,最大值将达到1.在更一般的情况下,最大值将更低并且必须确定阈值以确定信号是否足够相似。

您应该使用相关性而不是卷积。 相关峰值的大小告诉您两个信号的相似程度,峰值的位置及其相对位置,或两个信号之间的延迟。