检测音频零交叉的选项
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");
我有实时音频输入,我需要检测过零。
执行此操作的更简单算法,如 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");