天天看点

DSPF_sp_fftSPxSP_r2c函数的用法

文章属于原创内容,引用需注明出处!(尊重原创力量,人人做起)

一、准备工作

使用

DSPF_sp_fftSPxSP_r2c

DSPF_sp_ifftSPxSP_c2r

函数前,需要完成先

3

个工作:

1.二进制位翻转表(这个貌似是固定的),其代码如下;

// 二进制位翻转
#pragma DATA_ALIGN (brev, 8);  	// 8字节对齐
unsigned char brev[64] =
{
	0x00, 0x20, 0x10, 0x30, 0x08, 0x28, 0x18, 0x38,
	0x04, 0x24, 0x14, 0x34, 0x0c, 0x2c, 0x1c, 0x3c,
	0x02, 0x22, 0x12, 0x32, 0x0a, 0x2a, 0x1a, 0x3a,
	0x06, 0x26, 0x16, 0x36, 0x0e, 0x2e, 0x1e, 0x3e,
	0x01, 0x21, 0x11, 0x31, 0x09, 0x29, 0x19, 0x39,
	0x05, 0x25, 0x15, 0x35, 0x0d, 0x2d, 0x1d, 0x3d,
	0x03, 0x23, 0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b,
	0x07, 0x27, 0x17, 0x37, 0x0f, 0x2f, 0x1f, 0x3f
};
           

2.(逆)旋转因子

// 产生旋转因子
void tw_gen(float *w, int n)
{
    int i, j, k;

    for(i = 1, k = 0; i < n >> 2; i++)
    {
        w[k    ] = sin(2 * PI * i / n);
        w[k + 1] = cos(2 * PI * i / n);

        k += 2;
    }

    for(j = 1; j <= n >> 3; j = j << 2)  
    {
        for(i = 0; i < n >> 3; i += j)
        {
            w[k]     = (float)sin( 4 * PI * i / n);
            w[k + 1] = (float)cos( 4 * PI * i / n);
            w[k + 2] = (float)sin( 8 * PI * i / n);
            w[k + 3] = (float)cos( 8 * PI * i / n);
            w[k + 4] = (float)sin(12 * PI * i / n);
            w[k + 5] = (float)cos(12 * PI * i / n);

            k += 6;
        }
    }
}
// 逆fft变换的旋转因子
void tw_geni(float *w, int n)
{
    int i, j, k;

    for(i = 1, k = 0; i < n >> 2; i++)
    {
        w[k    ] =  sin (2 * PI * i / n);
        w[k + 1] = -cos (2 * PI * i / n);

        k += 2;
    }

    for(j = 1; j <= n >> 3; j = j << 2)
    {
        for(i = 0; i < n >> 3; i += j)
        {
            w[k]     = (float) -sin ( 4 * PI * i / n);
            w[k + 1] = (float)  cos ( 4 * PI * i / n);
            w[k + 2] = (float) -sin ( 8 * PI * i / n);
            w[k + 3] = (float)  cos ( 8 * PI * i / n);
            w[k + 4] = (float) -sin (12 * PI * i / n);
            w[k + 5] = (float)  cos (12 * PI * i / n);

            k += 6;
        }
    }
}

           

3.基的选择(不要多想,手动狗头),如果fft点数N是4的幂,rad为4,否则rad为2.

// 基
	unsigned char rad;
	if(N == 64 || N == 256 || N == 1024 || N == 4096 || N == 16384 || N == 65536)
	{
		rad = 4;
	}
	else if(N == 32 || N == 128 || N == 512 || N == 2048 || N == 8192 || N == 32768)
	{
		rad = 2;
	}
	else
	{
		printf ("不支持计算 %d 点快速傅里叶变换!\n", N);

		while(1);
	}
           

二、函数调用

1.fft变换函数的调用说明

DSPF_sp_fftSPxSP_r2c(N, Input, W, FFT_Out, brev, rad, offset, N);

N:复信号样本中FFT的长度

Input:指向复数数组输入的指针

W:指向复杂旋转因子的指针

(固定值)

FFT_Out: 指向复杂输出数据的指针

brev:指向包含64个条目的二进制位翻转表的指针

(固定值)

rad:如果fft点数N是4的幂,rad为4,否则rad为2

(根据N判定)

offset:从主fft开始的子fft复样本中的索引

(一般不需要使用偏移,因此为0)

n2:样本中主fft的大小

(一般是N)

有了第一步的准备工作,整个函数只需要指定输入输出即可成功调用。

DSPF_sp_ifftSPxSP_c2r(N, FFT_Out, W, IFFT_Out, brev, rad, offset, N);

逆fft变换函数的使用只需要注意旋转因子W利用tw_geni产生,其他的与上面大同小异,不再赘述

继续阅读