给定一个由320个元素(int16)组成的数组,表示持续20ms的音频信号(16位LPCM)。我正在寻找一种最简单和非常快速的方法,用来判断这个数组是否包含活动音频(如语音或音乐),而不是噪声或沉默。我不需要非常高质量的决策,但它必须非常快。
起初我想通过将所有元素的平方或绝对值相加,并将它们的总和与阈值进行比较,但这种方法在我的系统上非常慢,即使它是O(n)的。
起初我想通过将所有元素的平方或绝对值相加,并将它们的总和与阈值进行比较,但这种方法在我的系统上非常慢,即使它是O(n)的。
您不可能比平方总和方法更快。
一个可能没有尝试的优化是使用运行总数。也就是说,在每个时间步骤中,不要对最后n个样本的平方求和,而是保持运行总数,并使用最新样本的平方更新它。为了避免您的运行总数随着时间的推移不断增长,请添加指数衰减。伪代码如下:
decay_constant=0.999; // Some suitable value smaller than 1
total=0;
for t=1,...
// Exponential decay
total=total*decay_constant;
// Add in latest sample
total+=current_sample;
if total>threshold
// do something
end
end
这应该可以在数组中仅通过一次遍历来完成,您不需要复杂的算术运算,只需进行一些值的加法和比较即可。
另外,考虑一些近似值,例如仅取每四个值,从而将所检查的元素数量减少到80。对于音频信号,这应该是可以接受的。
我之前做过类似的事情。经过一些试验,我找到了一个在我的情况下工作得足够好的解决方案。
我使用了大约120毫秒内运行平均值的立方体变化率。当只有噪音(没有声音)时,表达式应该接近零。一旦速率在几次运行中开始增加,你可能有一些动作正在进行。
rate = cur_avg^3 - prev_avg^3
L
是指线性还是对数? - msw