【发布时间】:2015-12-01 04:15:51
【问题描述】:
我想对虚拟场景进行声音模拟。因此,我想以频率相关的方式将我的系统计算的脉冲响应与来自简单 .wav 文件的输入信号进行卷积。据我了解 DSP 最好的方法是使用 FFT 将输入信号转换为其频谱,以某种方式对其应用脉冲响应函数并将其返回。
我的问题是,在对我的信号进行 FFT 和 iFFT 之后,信号与原始输入信号不同。原始声音在新信号中是有一定的辨识度的,但由于 FFT 和 iFFT 之后的错误数字,它非常“模糊”。我从http://rosettacode.org/wiki/Fast_Fourier_transform#C.2B.2B 中获取了 C++ 中 FFT 的“第一”(就地、广度优先、频率抽取)实现示例。
下面是我的FFT实现的内码使用代码:
CArray signal = CArray(output_size);
for (int i = 0; i < format.FrameCount; ++i) {
signal[i] = Complex((double)(is_8_bit ? sample_data_8[i] : sample_data_16[i]), 0);
}
fft(signal);
ifft(signal);
存在以下typedef:
typedef std::complex<double> Complex;
typedef std::valarray<Complex> CArray;
由于我从上述网站获取代码,我认为错误不可能在 FFT 的实现范围内。我认为它必须与我输入的数据类型和/或复数有关。
由于我的系统没有实现“阶段”并且我读到它们可以被忽略并且仍然可以返回一个有用的值,所以我用 0 的虚部初始化复数。
我是否犯了一个根本性的错误,或者是数据类型或不应该出现的舍入之类的错误?
【问题讨论】:
-
采样率是多少?
-
@alexm 采样率为 22050Hz。
-
这只是一次拍摄,但要使 FFT 正常工作,您需要为其提供 2^n 个样本。
-
您在现场提供的第二个 FFT 函数对我来说无法正常工作!
-
@Logman 您的意思是“(就地、广度优先、频率抽取)”方法吗?目前,这种方法实际上为我抛出了内存分配异常;你也一样吗?第一个“分而治之”是我正在使用的。对不起,应该另外指出。第一个为我编译并执行,但不知何故似乎没有给我想要的结果。我还尝试了 48Hz 和 2^n 样本,不幸的是两者都有相似的结果。
标签: c++ signal-processing fft convolution