(收藏)FFT原理及实现(Radix-2)

转的,还是不太懂,有空的时候看看,大家也给提提意见。谢谢!

http://blog.csdn.net/sshcx/archive/2007/06/14/1651616.aspx

! 经过连续几个晚上的奋战, 终于弄懂了FFT推导过程及实现!  HappyJ

2 FFT总的思想是将输入信号对半分割, 再对半分割, 再再对半分割(以下省略10000个再再...J) 直至分割到2.

 

两点DFT简化

假设输入为x[0],x[1]; 输出为X[0],X[1].  伪代码如下 :

// ------------------------------------------------------------------

#define    N      2

#define    PI     3.1415926

 

// ------------------------------------------------------------------

int i, j

for(i=0, X[i]=0.0; i<N; i++)

    for(j=0; j<N; j++)

       X[i] += x[j] * ( cos(2*PI*i*j/N) - sin(2*PI*i*j/N) );

      

注意到(我想Audio编解码很多时候都是对cos,sin进行优化!)

 

j=0

j=1

 

i=0

cos  1

sin  0

 

tw   1

cos  1

sin  0

 

tw   1

 

i=1

cos  1

Sin  0

 

tw   1

cos  -1

sin  0

 

tw   -1

 

X[0] =   x[0]*(1-0) + x[1]*(1-0)  = x[0] + 1*x[1];

X[1] =   x[0]*(1-0) + x[1]*(-1-0) = x[0] - 1*x[1];

这就是单个2点蝶形算法.

 

FFT实现流程图分析(N=8, 8点信号为例)

FFT implementation of an 8-point DFT as two 4-point DFTs and four 2-point DFTs

8FFT流程图(Layer表示层, gr表示当前层的颗粒)

 

 

下面以LayerI为例.

LayerI部分, 具有4个颗粒, 每个颗粒2个输入

(注意2个输入的来源, 由时域信号友情提供, 感谢感谢J)

我们将输入x[k]分为两部分x_r[k], x_i[k]. 具有实部和虚部, 时域信号本没有虚部的, 因此可以让x_i[k]0. 那么为什么还要画蛇添足分为实部和虚部呢? 这是因为LayerII, LayerIII的输入是复数, 为了编码统一而强行分的.当然你编码时可以判断当前层是否为1来决定是否分. 但是我想每个人最后都会倾向分的.

旋转因子 tw = cos(2*PI*k/N)-j*sin(2*PI*k/N); 也可以分为实部和虚部, 令其为tw_r, tw_i;

tw = tw_r - j*tw_i;

 

X[k] = (x_r[k] + j*x_i[k]) + (tw_r–j*tw_i) * (x_r[k+N/2]+j*x_i[k+N/2])

           X_R[k] = x_r[k] + tw_r*x_r[k+N/2] + tw_i*x_i[k+N/2];

           X_I[k] = x_i[k] - tw_i*x_r[k+N/2] + tw_r*x_i[k+N/2];

 

 

 

LayerII部分, 具有2个颗粒, 每个颗粒4个输入

(注意4个输入的来源, LayerI友情提供, 感谢感谢J)

 

 

 

LayerIII部分, 具有1个颗粒, 每个颗粒8个输入

(注意8个输入的来源, LayerII友情提供, 感谢感谢J)

 

LayerI, LayerII, LayerIII从左往右, 蝶形信号运算流非常明显!

 

 

 

 

假令输入为x[k], x[k+N/2], 输出为X[k], X[k+N/2]. x[k]分解为x_r[k], x_i[k]部分

则该蝶形运算为

X[k]

 = (x_r[k]-j*x_i[k]) + (x_r[k+N/2]-j*x_i[k+N/2])*(cos(2*PI*k/N)-j*sin(2*PI*k/N));

再令cos(2*PI*k/N)tw1, sin(2*PI*k/N)tw2

X[k] = (x_r[k]-j*x_i[k]) + (x_r[k+N/2]-j*x_i[k+N/2])*(tw1-j*tw2);

 

X_R[k] = x_r[k] + x_r[k+N/2]*tw1 -  x_i[k+N/2]*tw2;

X_I[K] = x_i[k]

 

 

 

 

 

 

 

 

 

              x_r[k] = x_r[k] + x_r[k+b]*tw1 + x_i[k+b]*tw2;

              x_i[k] = x_i[k] - x_r[k+b]*tw2 + x_i[k+b]*tw1;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

譬如8点输入x[8]

1. 先分割成2部分:  x[0], x[2], x[4], x[6] x[1], x[3], x[5], x[7]

2. 信号x[0], x[2], x[4], x[6]再分割成x[0], x[4] x[2], x[6]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值