我正试图检测来自麦克风的声音中的一些回声。回波将是周期性的,并且是两种可能的偏移之一。我听说我需要自动关联信号的倒谱,以便检测这些回声的存在。您能否使用Accelerate框架提供代码,该框架显示如何检测音频数据中的回声?
答案 0 :(得分: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之后,您可能根本没有发现峰值,而只是随机重复性因子。尽管如此,尝试使用不同的窗口大小来查看为您提供最可靠的结果。
答案 1 :(得分:0)
自相关基本上是信号与其自身的互相关,其基本上是通过一定的时间延迟检测信号本身的相似性。在信号中搜索回波实际上是一个好主意。虽然我无法向您提供最准确和正确的解决方案,但您可以使用以下链接中的信息编写自己的解决方案。
已经有一些答案:
Kunal Kandekar 在Github上为vDSP(加速框架)提供了源代码。这可能是一个很好的起点。
答案 2 :(得分:0)
如果你知道回声延迟长度,你可以构建一个更有效的滤波器:
https://dsp.stackexchange.com/questions/14951/trivial-echo-separation
你在哪里阅读使用倒谱?