检测音频零交叉的选项

Options for detecting zero cross of audio

我有实时音频输入,我需要检测过零。

执行此操作的更简单算法,如 this question 所述,不能满足我的需要。该算法通过取当前项与前一项相乘的符号来检测过零。

这是此方法失败的一个简单示例:

-1, -0.5, 0, 0, 0.32, 0.5...

连续两个零,算法将失败。

这个方法是这样实现的:

int sign(float value) {
  if (value < 0) {
    return -1;
  } else if (value > 0) {
    return 1;
  }
  return 0;
}

for (int i=0; i<numFrames-1; i++) {
    int signR = sign(data[i+1] * data[i]);        
    if (signR == 0) printf("zero cross");
    // but this will fail for data[i+1] = data[i] = 0, for example

}

我还必须使用哪些其他算法选项来检测过零?

记录最后一个非零样本的符号,如果当前样本也非零(零样本本身永远不会交叉),则只考虑乘法结果。

for (int i=0, previous=sign(data[0]); i<numFrames-1; i++) {
    if(int current = sign(data[i])) {
        if(sign(previous * current) == -1)
            printf("zero cross");
        previous = current;
    }
}

忽略该值,仅使用标志检测交叉。

#include <math.h>

for (int i=0; i<numFrames-1; i++) {
  if (signbit(data[i+1]) != signbit(data[i])) printf("zero cross");
}

The signbit macro reports the sign of all values, including infinities, zeros, and NaNs.

[编辑]

signbit() return 当且仅当其参数值的符号为负时,它是一个非零值。所以 2 个不同的负值可能 return 不同的非零值。更好用:

  if (!signbit(data[i+1]) != !signbit(data[i])) printf("zero cross");