简介:
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 */
然后一个用的比较多的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 */
);
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 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