我正在为数字信号处理编写信号源,但发现了奇怪的行为。以下是代码:
float complex *output = malloc(sizeof(float complex) * 48000);
FILE *f = fopen("test_signal.cf32", "wb");
int64_t freq = -3355;
float phase_increment = 2 * (float) M_PI * (float) freq / 48000;
float phase = 0.0F;
for (int i = 0; i < 150 * 5; i++) {
for (int j = 0; j < 9600; j++) {
output[j] = cosf(phase) + sinf(phase) * I;
phase += phase_increment;
}
fwrite(output, sizeof(float complex), 9600, f);
}
fclose(f);
它将创建一个复杂信号的文件,该信号从中心向左偏移-3355Hz。因此,当我在此文件上运行FFT时,我期望在-3355Hz处获得信号。由于量化,可能会在该数字周围有一些次要频率分布。但实际情况是我得到了以下结果:
大约在50秒左右,频率出现了相当显著的跳变(~2000hz)。
有人知道原因吗?
我的实验表明:
- 使用双精度浮点数的
phase
有所帮助 - 将参数从-2pi到2pi进行减少有所帮助
- 苹果M1和树莓派有相同的跳变
phase
参数似乎没有溢出- 有趣的阅读https://randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by-1-3-quintillion/,但不太可能导致频率突然跳变
output[j] = cosf(phase) + sinf(phase) * I;
中,这个大写的I
是不是和小写的i
不同的变量?如果是的话,那这个I
变量是什么? - user8849929complex.h
导入的虚数单位。 - tstanislsin()
的 MS man page 表示:“如果 x 大于或等于 263,或小于或等于 -263,则结果会出现精度损失。” - Weather Vane