【问题标题】:Auto-correlating the cepstrum自相关倒谱
【发布时间】:2014-03-10 16:09:34
【问题描述】:

我正在尝试检测来自麦克风的声音中的一些回声。回波将是周期性的,并且处于两个可能的偏移之一。我听说我需要自动关联信号的倒谱以检测这些回波的存在。您能否提供使用 Accelerate 框架的代码来展示如何检测音频数据中的回声?

【问题讨论】:

  • 我以为你的意思是说“频谱”,所以我决定查找倒谱 - 每天学习新东西!

标签: ios objective-c audio signal-processing accelerate-framework


【解决方案1】:

我不完全确定您为什么要自动关联倒谱。但是,自动相关为您提供了与倒谱相关的表示,因此我假设您只想自动关联您的信号。

最简单的形式如下:

int sample      = 0;
int sampleMax   = inSize;

while( sample < sampleMax )
{
            vDSP_vsmul( pInput, 1, pInputSample, tempBuffer, 1, sampleMax );

    const size_t kAutoCorrWritePos  = outSize - sampleMax - sample;
            vDSP_vsadd( &pOutput[kAutoCorrWritePos], 1, tempBuffer, 1, &pOutput[kAutoCorrWritePos], 1, sampleMax )
    sample++;
}

但是,这是一个非常缓慢的操作。值得庆幸的是,相关性可以通过几种不同的方式进行。最快的方法是执行 FFT,将复数值乘以其自身的共轭,然后逆 fft。

或者在 iOS 中你有很好的优化 vDSP_conv 函数:

std::vector< float > paddedBuffer( (inSize + inSize) - 1 );
memcpy( &paddedBuffer.front(), pInput, sizeof( float ) * inSize );
vDSP_conv( &paddedBuffer.front(), 1, (float*)pInput, 1, (float*)pOutput + (inSize - 1), 1, inSize, inSize );

// Reflect the auto correlation for the true output.
int posWrite    = (inSize - 1);
int posRead     = (inSize - 1);
while( posWrite > 0 )
{
    posWrite--;
    posRead++;

    pOutput[posWrite] = pOutput[posRead];
}

所以现在你有了自动关联,你会用它做什么?

首先在中间,您将拥有最高峰。这是零滞后点。然后您要做的是扫描该中心峰的右侧以识别次峰。如果您正在寻找特定偏移处的特定峰,您可以简单地检查中心峰上的样本数并检查那里是否有峰。如果没有,那么您正在寻找的信号不存在。如果它在那里,信号就在那里。

编辑:值得注意的是,如果您正在查看的延迟超过约 128,则使用 512 样本宽的窗口可能无法获得足够的相关信号以可以发现。相关性通过在样本数据中的重复信号点处提供峰值来起作用。在 128 的延迟时,您有足够的数据来重复该点 4 次。在 256 处,您只能看到该点重复两次。这将影响相关峰的高度。在 256 之后,您可能根本无法仅针对随机重复性因素发现峰值。尽管如此,您可以尝试不同的窗口大小,看看什么可以为您提供最可靠的结果。

【讨论】:

  • 非常感谢。所以 inSize 将是我的缓冲区大小(在我的情况下为 512)?如果我的来自麦克风的声音数据变量是 float* 数据​​,那么这将代表 pInput?
  • @codeman:是的,你在 inSize 上是对的。确切地。如果它不是浮点数,那么您需要将它们转换为浮点数。
  • 谢谢 Goz。 pOutput 应该如何定义/分配?
  • 我是这样的:pOutput = (float *) malloc(inSize * sizeof(float));但是我收到了这个错误: malloc: *** error for object 0xbbfe404: wrong checksum for freed object - object was possible modified after being freed.
  • 仍然给我这个错误:malloc: *** 对象 0xb356c04 错误:已释放对象的校验和不正确 - 对象可能在被释放后被修改。
【解决方案2】:

自相关基本上是信号与其自身的互相关,它基本上是通过一定的时间延迟检测信号本身的相似性。这实际上是在信号中搜索回声的好主意。虽然我无法为您提供最准确和正确的解决方案,但您应该能够使用以下链接中的信息编写自己的解决方案。

已经有一些答案了:

Kunal Kandekar 在 Github 上有可用于 vDSP(加速框架)的源代码。这可能是一个很好的起点。

https://github.com/kunalkandekar/vDSPxcorr

【讨论】:

    【解决方案3】:

    如果您知道回声延迟长度,您也许可以构建一个更有效的滤波器:

    https://dsp.stackexchange.com/questions/14951/trivial-echo-separation

    您在哪里阅读以使用倒谱?

    【讨论】:

      猜你喜欢
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 2011-06-22
      • 2012-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多