我在理解如何正确使用KissFFT(1.2.9)时遇到了一些麻烦。我现在想要实现的是执行FFT然后立即执行iFFT以再次重建原始信号。下面的代码片段演示了我正在做的事情:
void test(short* timeDomainData, int length)
{
// Create the configurations for FFT and iFFT...
kiss_fftr_cfg fftConfiguration = kiss_fftr_alloc( length, 0, NULL, NULL );
kiss_fftr_cfg ifftConfiguration = kiss_fftr_alloc( length, 1, NULL, NULL );
// Allocate space for the FFT results (frequency bins)...
kiss_fft_cpx* fftBins = new kiss_fft_cpx[ length / 2 + 1 ];
// FFT...
kiss_fftr( fftConfiguration, timeDomainData, fftBins );
// iFFT...
kiss_fftri( ifftConfiguration, fftBins, timeDomainData );
}
我发现这实际上是在运行时崩溃了。我发现在创建KissFFT配置时将大小除以2会停止崩溃:
kiss_fftr_cfg fftConfiguration = kiss_fftr_alloc( length / 2, 0, NULL, NULL );
kiss_fftr_cfg ifftConfiguration = kiss_fftr_alloc( length / 2, 1, NULL, NULL );
然而,当我播放重建的音频数据时,它大部分都是奇怪的噼啪声。
有人能指出我正确的方向吗?
非常感谢, P
编辑1:这是我包含KissFFT头文件并定义FIXED_POINT变量的方式:
#define FIXED_POINT 16
#include "kiss_fftr.h"
这确保了typedef'd'kiss_fft_scalar'类型被强制为int16_t(短)。
编辑2:目标平台是Android,因此我还在Android.mk文件中添加了以下内容:
LOCAL_CPPFLAGS += -DFIXED_POINT
答案 0 :(得分:0)
我注意到你穿着短裤。你确定你已经编译了所有东西以使用int16_t作为DATATYPE吗?有时,预处理器环境的不匹配会导致问题。
此外,定点版本向下缩放两个方向(fwd,inv)。因此,如果您希望重建信号,那么您需要将总数乘以nfft。 我建议分两个阶段乘以饱和度。
e.g。如果您正在进行大小为1024的FFT + IFFT,则在FFT之后再乘以32,然后在IFFT之后再乘以32.
答案 1 :(得分:0)
我不确定沉默,但是如果你得到很多噼啪声,那么它可能是因为你独立处理相邻的块而不是使用Overlap-Add,你可以在每个块之间有效地交叉淡入淡出获得更平滑的特征。
答案 2 :(得分:0)
我正在努力在Android中做同样的事情,尚未得到它(请参阅here!),但我可以在您的代码中看到问题:“fftBins”需要“长度”大小。原因是它是原始变换,而不是频率幅度/阶段......我想?或者我弄错了?