最近做音频信号处理的时候,需要对数据做fft变换。关于fft原理:
请参考:FFT算法讲解——麻麻我终于会FFT了!
matlab实现fft函数很简单,直接调用fft即可。但java实现起来就有点难了。参考了比较好两篇java实现的博客:
A.Java实现算法导论中快速傅里叶变换FFT递归算法
B.快速傅里叶变换及java实现
通过比对。A博客只实现了数组长度是2的幂次的函数,其他就没有实现,B博客是实现了所有的,但其中有几处错误。最后实现方法如下:
1)FFT函数
这个函数A和B基本上差不多,但B博客的n为1时,返回要改一下。
public static Complex[] fft(Complex[] x) {
int n = x.length;
// 因为exp(-2i*n*PI)=1,n=1时递归原点
if (n == 1){
// 这里和B博客中有一点变化
return new Complex[]{x[0]};
}
// 如果信号数为奇数,使用dft计算
if (n % 2 != 0) {
return dft(x);
}
// 提取下标为偶数的原始信号值进行递归fft计算
Complex[] even = new Complex[n / 2];
for (int k = 0; k < n / 2; k++) {
even[k] = x[2 * k];
}
Complex[] evenValue = fft(even);
// 提取下标为奇数的原始信号值进行fft计算
// 节约内存
Complex[] odd = even;
for (int k = 0; k < n / 2; k++) {
odd[k] = x[2 * k + 1];
}
Complex[] oddValue = fft(odd);
// 偶数+奇数
Complex[] result = new Complex[n];
for (int k = 0; k < n / 2; k++) {
// 使用欧拉公式e^(-i*2pi*k/N) = cos(-2pi*k/N) + i*sin(-2pi*k/N)
double p = -2 * k * Math.PI / n;
Complex m &#