我的音频信号上有一种FM编码信号。编码信号使用this Biphase mark coding technique< - 请参阅本页末尾。
此信号是时间码的数字表示,以小时,分钟,秒和帧为单位。它基本上是这样的:
我的代码是这样做的:
这是代码:
// data is a C array of floats representing the audio levels
float bitPeriod = ceil(44100 / 2000);
int firstZeroCrossIndex = findNextZeroCross(data);
// firstZeroCrossIndex is the value where the signal changed
// for example: data[0] = -0.23 and data[1] = 0.5
// firstZeroCrossIndex will be equal to 1
// if firstZeroCrossIndex is invalid, go away
if (firstZeroCrossIndex < 0) return
float firstValue = data[firstZeroCrossIndex];
int lastSignal = sign(firstValue);
if (lastSignal == 0) return; // invalid, go away
while (YES) {
float newValue = data[firstZeroCrossIndex + 0.75* bitPeriod];
int newSignal = sign(newValue);
if (lastSignal == newSignal)
printf("0");
else
printf("1");
firstZeroCrossIndex += bitPeriod;
// I think I must invert the signal here for the next loop interaction
lastSignal = -newSignal;
if (firstZeroCrossIndex > maximuPossibleIndex)
break;
}
这段代码对我来说是合乎逻辑的,但是来自它的结果完全是胡说八道。我错过了什么?
注意:此代码通过实时信号执行,并从循环环形缓冲区读取值。如果值为负,则sign
返回-1;如果值为正,则返回1;如果值为零,则返回0。
答案 0 :(得分:2)
很酷的问题! : - )
代码以两种独立的方式失败:
您正在搜索第一个(任意)过零点。这很好。但是有50%的可能性,这个转换发生在每个位(0
或1
)之前或者此转换是否标记为{ {1}}位。如果你在开始时弄错了,你最终会胡说八道。
您继续将1
(float,22.05)添加到bitPeriod
(int)。这意味着您的采样点将慢慢与模拟信号不同相,当采样点接近信号转换时,您将看到奇怪的效果。你至少会定期得到胡说八道。
解决方案1:您必须首先搜索至少一个firstZeroCrossIndex
,以便知道哪个转换仅指示下一位,哪个指示0
位。实际上,您需要在每个'0'位重新同步您的采样器。
解决方案2:不要将1
添加到您的采样点。而是像在开始时一样搜索下一个转换。下一个转换要么是“半个”,要么是“完整位”,它可以为您提供所需的信息。在“半个小时”之后,你必须看到另一个'半个'时期。如果没有,则必须重新同步,因为您意外地进行了开始转换的中间转换。这正是我在1中谈论的重新同步。