IOS 快速傅立叶变换(使用系统框架vDSP)

来源:互联网 发布:查金融客户数据 编辑:程序博客网 时间:2024/05/16 08:19

简介:

vDSP的API提供了一维信号与二维信号,在时域与频域中的傅立叶变换。(这里只翻译一维信号)


FFT权重数组:

为了更好的精度,vDSP处理频域的函数需要一个已经存在的,复杂的指数数组来调用。一旦创建一次,那么所有的FFT变换就可以共享这个数组。这个权重数组可以使用vDSP_create_fftsetup(single-precision) 或者vDSP_create_fftsetupD(double-precision)来创建。在调用变换函数之前必须至少调用一次这个函数。开始要先确定变换点数,来建立函数:

(1)为数组创建一个数据块。

(2)创建数组(写数据)。

(3)保存得到的指针。

一定要确保这个指针不为空。


参数 log2n 是以2为低 n的对数。这里的n是最大要傅立叶变换的点数。 比如进行1024点的快速傅立叶变换 ,那就写10。

FFTsetup setup=vDSP_create_fftsetup( 11, 0 ); /* supports up to 2048 (2**11)points  */

用完后释放,释放函数:

 vDSP_destroy_fftsetup(setup);


快速傅立叶变换代码:
vDSP_fft_zrip( setup, small_set, 1, 8, FFT_FORWARD); /* 256 (2**8) points  */

逆变换就是把 FFT_FORWARD 改为 FFT_INVERSE

然后一个用的比较多的DSP函数 顺序相乘函数:
void vDSP_vmul(    float *input_1, /* input vector 1 */    SInt32 stride_1, /* address stride for input vector 1 */    float *input_2, /* input vector 2 */    SInt32 stride_2, /* address stride for input vector 2 */    float *result, /* output vector */    SInt32 strideResult, /* address stride for output vector */    UInt32 size /* real output count */

); 

/* Multiply sequential values of two 1,024-point vectors */float a[1024], b[1024], c[1024];vDSP_vmul( a, 1, b, 1, c, 1, 1024 );//结果就是 c[i]=a[i]*b[i],i=0~1024; 3个1的参数,大概也能猜出来,是跳位的,测试一下就明白了


最后加上我翻译后封装的 快速傅立叶变换 函数,需要自己开辟 COMPLEX_SPLIT 空间再调用

 COMPLEX_SPLIT jubufferdata;

 jubufferdata.realp=(Float32 *)malloc(NFFt*sizeof(Float32));

 jubufferdata.imagp=(Float32 *)malloc(NFFt*sizeof(Float32));

        



#import <Foundation/Foundation.h>

#import <Accelerate/Accelerate.h>


@interface FFTWManager : NSObject


-(id)initWithMaxP:(int) maxp; // maxp:傅立叶变换最大点数


-(void)FFTMRelease;


-(void)FFT:(COMPLEX_SPLIT *)inOutData lengnth:(long) numofp; //快速傅立叶变换(结构体指针)

-(void)IFFT:(COMPLEX_SPLIT *)inOutData lengnth:(long) numofp; //快速傅立叶逆变换(结构体指针)


-(void)XiangCheng:(Float32 *)indataA B:(Float32 *)indataB OUT:(Float32 *)outData lenght:(long)numofp;


//-(COMPLEX *)FFTC:(COMPLEX *)inputData lengnth:(long) numofp; //快速傅立叶变换(结构体数组慢一点

//-(COMPLEX *)IFFTC:(COMPLEX *)inputData lengnth:(long) numofp; //快速傅立叶逆变换(结构体数组慢一点


@end


#import "FFTWManager.h"

#include <MacTypes.h>


@implementation FFTWManager

{

    FFTSetup _fftSetup;

    COMPLEX_SPLIT _complexA;

    

//    COMPLEX *_outFFTData;

}

-(id)initWithMaxP:(int) maxp

{

    self=[super init];

    if (self) {

        

        vDSP_Length log2n = log2f(maxp);

        _fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);


//        int nOver2 =maxp;// maxp/2;

        

//        _complexA.realp = (Float32*)malloc(nOver2*sizeof(Float32));

//        _complexA.imagp = (Float32*)malloc(nOver2*sizeof(Float32));

        

//        _outFFTData =(COMPLEX *)malloc(maxp*sizeof(COMPLEX));

    

    }

    return self;

}

-(void)FFTMRelease

{

    vDSP_destroy_fftsetup(_fftSetup);

//    free(_complexA.realp);

//    free(_complexA.imagp);

//    free(_outFFTData);

}



-(void)FFT:(COMPLEX_SPLIT *)inOutData lengnth:(long) numofp

{

    vDSP_Length log2n = log2f(numofp*2);

    vDSP_fft_zrip(_fftSetup,inOutData,1,log2n, FFT_FORWARD);

}

-(void)IFFT:(COMPLEX_SPLIT *)inOutData lengnth:(long) numofp

{

    vDSP_Length log2n = log2f(numofp*2);

    vDSP_fft_zrip(_fftSetup,inOutData,1,log2n, FFT_INVERSE);

    

    Float32 normf=1.0/(4*numofp);

    

    vDSP_vsmul(inOutData->realp, 1, &normf,inOutData->realp,1,numofp);

    vDSP_vsmul(inOutData->imagp, 1, &normf,inOutData->imagp,1,numofp);

}

-(void)XiangCheng:(Float32 *)indataA B:(Float32 *)indataB OUT:(Float32 *)outData lenght:(long)numofp

{

    vDSP_vmul(indataA,1,indataB,1,outData,1,numofp);

}


//-(COMPLEX *)FFTC:(COMPLEX *)inputData lengnth:(long) numofp

//{

//    vDSP_Length log2n = log2f(numofp*2);

//

//    vDSP_ctoz(inputData,2, &(_complexA),1, numofp);// 结构体数组  指针结构体

//    

//    vDSP_fft_zrip(_fftSetup, &(_complexA), 1, log2n, FFT_FORWARD);//做变换

//    

//    vDSP_ztoc(&(_complexA),1,_outFFTData,2,numofp);// 指针结构体  结构体数组

//

////    vDSP_zvmags(&(_complexA), 1,_outFFTData, 1, numofp);//平方和 模值

//    

//    return _outFFTData;

//}

//-(COMPLEX *)IFFTC:(COMPLEX *)inputData lengnth:(long) numofp

//{

//    vDSP_Length log2n = log2f(numofp*2);

//    

//    vDSP_ctoz(inputData,2, &(_complexA),1, numofp);// 结构体数组  指针结构体

//    

//    vDSP_fft_zrip(_fftSetup, &(_complexA), 1, log2n, kFFTDirection_Inverse);//做逆变换

//    

//    vDSP_ztoc(&(_complexA),1,_outFFTData,2,numofp);// 指针结构体  结构体数组

//    

//    return _outFFTData;

//}

@end

0 0
原创粉丝点击