annotate src/btrack_plus/accFFT.cpp @ 0:3dcbd77efc94

added files for OF project
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Fri, 21 Sep 2012 16:35:17 +0100
parents
children eb29c6b6dff8
rev   line source
andrew@0 1 //
andrew@0 2 // accFFT.cpp
andrew@0 3 // AccelerateFFTtool
andrew@0 4 //
andrew@0 5 // Created by Adam Stark on 17/07/2012.
andrew@0 6 // Copyright (c) 2012 __MyCompanyName__. All rights reserved.
andrew@0 7 //
andrew@0 8
andrew@0 9 #include "accFFT.h"
andrew@0 10
andrew@0 11
andrew@0 12 accFFT :: accFFT(int fft_size,int type)
andrew@0 13 {
andrew@0 14 fft_type = type;
andrew@0 15
andrew@0 16 fftSize = fft_size;
andrew@0 17 fftSizeOver2 = fftSize/2;
andrew@0 18 log2n = log2f(fftSize);
andrew@0 19 log2nOver2 = log2n/2;
andrew@0 20
andrew@0 21 if (fft_type == 0)
andrew@0 22 {
andrew@0 23 split.realp = (float *) malloc(fftSize * sizeof(float));
andrew@0 24 split.imagp = (float *) malloc(fftSize * sizeof(float));
andrew@0 25
andrew@0 26 // allocate the fft object once
andrew@0 27 fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);
andrew@0 28 if (fftSetup == NULL) {
andrew@0 29 //printf("FFT Setup failed\n");
andrew@0 30 }
andrew@0 31 }
andrew@0 32 else if (fft_type == 1)
andrew@0 33 {
andrew@0 34 d_split.realp = (double *) malloc(fftSize * sizeof(double));
andrew@0 35 d_split.imagp = (double *) malloc(fftSize * sizeof(double));
andrew@0 36
andrew@0 37 // allocate the fft object once
andrew@0 38 fftSetupD = vDSP_create_fftsetupD(log2n, FFT_RADIX2);
andrew@0 39 if (fftSetupD == NULL) {
andrew@0 40 //printf("FFT Setup failed\n");
andrew@0 41 }
andrew@0 42 }
andrew@0 43
andrew@0 44
andrew@0 45
andrew@0 46 }
andrew@0 47
andrew@0 48 accFFT :: ~accFFT()
andrew@0 49 {
andrew@0 50 if (fft_type == 0)
andrew@0 51 {
andrew@0 52 free(split.realp);
andrew@0 53 free(split.imagp);
andrew@0 54 vDSP_destroy_fftsetup(fftSetup);
andrew@0 55 }
andrew@0 56 else if (fft_type == 1)
andrew@0 57 {
andrew@0 58 free(d_split.realp);
andrew@0 59 free(d_split.imagp);
andrew@0 60 vDSP_destroy_fftsetupD(fftSetupD);
andrew@0 61 }
andrew@0 62
andrew@0 63
andrew@0 64 }
andrew@0 65
andrew@0 66 void accFFT :: forward_FFT_f(float *buffer,float *real,float *imag)
andrew@0 67 {
andrew@0 68 //convert to split complex format with evens in real and odds in imag
andrew@0 69 vDSP_ctoz((COMPLEX *) buffer, 2, &split, 1, fftSizeOver2);
andrew@0 70
andrew@0 71 //calc fft
andrew@0 72 vDSP_fft_zrip(fftSetup, &split, 1, log2n, FFT_FORWARD);
andrew@0 73
andrew@0 74 // set Nyquist component to imaginary of 0 component
andrew@0 75 split.realp[fftSizeOver2] = split.imagp[0];
andrew@0 76 split.imagp[fftSizeOver2] = 0.0;
andrew@0 77
andrew@0 78 // set 0 component to zero
andrew@0 79 split.imagp[0] = 0.0;
andrew@0 80
andrew@0 81 // multiply by 0.5 to get correct output (to do with Apple's FFT implementation)
andrew@0 82 for (i = 0; i <= fftSizeOver2; i++)
andrew@0 83 {
andrew@0 84 split.realp[i] *= 0.5;
andrew@0 85 split.imagp[i] *= 0.5;
andrew@0 86 }
andrew@0 87
andrew@0 88 // set values above N/2+1 which are complex conjugate mirror image of those below
andrew@0 89 for (i = fftSizeOver2 - 1;i > 0;--i)
andrew@0 90 {
andrew@0 91 split.realp[2*fftSizeOver2 - i] = split.realp[i];
andrew@0 92 split.imagp[2*fftSizeOver2 - i] = -1*split.imagp[i];
andrew@0 93
andrew@0 94 //cout << split_data.realp[2*fftSizeOver2 - i] << " " << split_data.imagp[2*fftSizeOver2 - i] << "i" << endl;
andrew@0 95 }
andrew@0 96
andrew@0 97 for (i = 0;i < fftSize;i++)
andrew@0 98 {
andrew@0 99 real[i] = split.realp[i];
andrew@0 100 imag[i] = split.imagp[i];
andrew@0 101 }
andrew@0 102 }
andrew@0 103
andrew@0 104
andrew@0 105
andrew@0 106 void accFFT :: forward_FFT_d(double *buffer,fft_complex *out)
andrew@0 107 {
andrew@0 108 //convert to split complex format with evens in real and odds in imag
andrew@0 109 vDSP_ctozD((DOUBLE_COMPLEX *) buffer, 2, &d_split, 1, fftSizeOver2);
andrew@0 110
andrew@0 111 //calc fft
andrew@0 112 vDSP_fft_zripD(fftSetupD, &d_split, 1, log2n, FFT_FORWARD);
andrew@0 113
andrew@0 114 // set Nyquist component to imaginary of 0 component
andrew@0 115 d_split.realp[fftSizeOver2] = d_split.imagp[0];
andrew@0 116 d_split.imagp[fftSizeOver2] = 0.0;
andrew@0 117
andrew@0 118 // set 0 component to zero
andrew@0 119 d_split.imagp[0] = 0.0;
andrew@0 120
andrew@0 121 // multiply by 0.5 to get correct output (to do with Apple's FFT implementation)
andrew@0 122 for (i = 0; i <= fftSizeOver2; i++)
andrew@0 123 {
andrew@0 124 d_split.realp[i] *= 0.5;
andrew@0 125 d_split.imagp[i] *= 0.5;
andrew@0 126 }
andrew@0 127
andrew@0 128 // set values above N/2+1 which are complex conjugate mirror image of those below
andrew@0 129 for (i = fftSizeOver2 - 1;i > 0;--i)
andrew@0 130 {
andrew@0 131 d_split.realp[2*fftSizeOver2 - i] = d_split.realp[i];
andrew@0 132 d_split.imagp[2*fftSizeOver2 - i] = -1*d_split.imagp[i];
andrew@0 133 }
andrew@0 134
andrew@0 135 for (i = 0;i < fftSize;i++)
andrew@0 136 {
andrew@0 137 out[i][0] = d_split.realp[i];
andrew@0 138 out[i][1] = d_split.imagp[i];
andrew@0 139 }
andrew@0 140 }