void FFT(float*x, float*X, unsigned short M) { int N; N = (int) 2*M; //Integer of merit for many functions called herein. Equal to the number of complex values that'll be in 'X' (which is twice as many as in 'x') int a; //Counter variable, gets used in several "for" loops. int b; /*This will be used for some of the bookkeeping in the loop immediately below */ int c; /*Similar to b, this is used for different matrix indexing.*/ for (a=0; a<M; a++) //Assign the data from x to every other slot in X, inserting zeroes in-between. { b=2*a; c=1+2*a; X[b]=x[a]; X[c]=0; } for (a=2*M; a<2*N; a++) //Appends the additional zeroes on to the end. Note that this is both the real and imaginary elements { X[a]=0; } float* w =(float*)malloc(sizeof(float)*M); //"w," twiddle-factor container, must be defined in this way since its length depends on a variable gen_w_r2(w,N); //Twiddle factor generation; function prototyped and included below //------ACTUAL FFT HERE:---------------- bit_rev(w, N >> 1); DSPF_sp_cfftr2_dit(X,w,N); /*bit_rev(X,N); */ /* These to bits (bit_rev & 'for' loop) are the parts that make the 'raw' outputs look like the Matlab outputs. To * re-include them in the code to be compiled, simply remove the comments around them. */ /* for (a=0;a<2*N;a=a+2) { x[a+1]=-x[a+1]; } */ //-------------------------------------- }
void main(void) { float A[128] = {43.000000,0.000000, 3.616321,30.125547, -14.479670,-2.567202, 12.362492,-21.842867, 32.385956,13.828468, -7.707342,18.480019, 1.519983,-3.868871, 4.327905,-4.279924, 20.798990,2.485281, 2.305606,11.042850, 16.090977,2.064070, 5.466386,19.738562, 0.345887,10.251665, -3.438493,4.526769, 12.931265,9.287642, -14.795074,12.285769, 17.000000,-10.000000, 4.956760,30.588863, -4.126019,7.640384, -12.621098,21.370527, -6.488023,-10.174742, 1.631006,20.984383, -14.443722,-3.912756, 6.433661,14.007210, -18.798990,14.485281, -23.586613,0.723100, -5.995662,-12.674122, -23.052052,8.538252, -10.243816,-50.597946, 35.359089,3.127013, 8.502851,-7.042882, 24.741423,53.781017, -81.000000,0.000000, 24.741428,53.781006, 8.502846,-7.042882, 35.359089,3.127012, -10.243820,-50.597939, -23.052046,8.538255, -5.995665,-12.674120, -23.586613,0.723101, -18.798990,14.485281, 6.433663,14.007207, -14.443724,-3.912753, 1.631013,20.984381, -6.488022,-10.174742, -12.621092,21.370529, -4.126016,7.640386, 4.956764,30.588863, 17.000000,-10.000000, -14.795071,12.285774, 12.931269,9.287637, -3.438493,4.526770, 0.345886,10.251665, 5.466391,19.738560, 16.090977,2.064065, 2.305608,11.042850, 20.798990,2.485281, 4.327904,-4.279922, 1.519982,-3.868872, -7.707339,18.480021, 32.385952,13.828463, 12.362488,-21.842869, -14.479672,-2.567199, 3.616327,30.125546}; unsigned short N=64; //There're 64 complex numbers in A, taking up 128 array entries. //PRINT FFT'd VALUES (inputs) printf("Original Inputs (Results of an FFT w/ Post-Processing (a-la Matlab):"); printf("\n"); int i; int a; for(i=0;i<N;i=i+2) { printf("%f",A[i]); printf(" "); printf("%f i",A[i+1]); printf("\n"); } printf("\n"); float* w =(float*)malloc(sizeof(float)*(N/2)); gen_w_r2(w,N); bit_rev(w, N>>1 ); printf("\n"); //"Fixing" the FFT results; I.E. undoing post-processing---------------- for (a=0;a<N;a=a+2) { A[a+1]=-A[a+1]; } bit_rev(A,N); //---------------------------------------------------------------------- printf("FFT'd Results, WITHOUT Post-Processing"); printf("\n"); for (i=0;i<N;i=i+2) { printf("%f",A[i]); printf(" "); printf("%f",A[i+1]); printf(" i;"); printf("\n"); } printf("\n"); //IFFT here: DSPF_sp_icfftr2_dif(A,w,N); //Scale by N for (i = 0; i < N*2; i++) /*ACHTUNG! Originally the limiting condition was "i < N*2" because "N" represents the number of COMPLEX numbers in the array; since it takes two array entries (real & imaginary) to represent one complex\ number, the array is twice as long as this "N." If there's a problem with the IFFT, consider changing this first to see if anything's solved.*/ { A[i] /= N; } printf("IFFT'd Final Outputs"); printf("\n"); //PRINT IFFT'd VALUES (OUTPUTS) for (i=0;i<N;i=i+2) { printf("%f",A[i]); printf(" "); printf("%f",A[i+1]); printf(" i;"); printf("\n"); } //Now we should have no complex values, so even indices of Y are real-valued and odd (cpx) indices or Y are zeroes. We now chop out //these interstitial zeroes float* y =(float*)malloc(sizeof(float)*((N/2)-1)); for (i=0; i<N;i++) { y[i]=A[2*i]; } }
/* Constructor Input arguments: t_nLPC: LPC order t_sr: sampling rate of the input signal (Hz) t_bufferSize: input buffer size (# of samples) t_nFFT: FFT length (must be power of 2) t_cepsWinWidth: cepstral liftering window width (dimensionless) t_nTracks: Number of formants to be tracked t_aFact: alpha parameter in the DP formant tracking algorithm (Xia and Espy-Wilson, 2000) t_bFact: beta t_gFact: gamma t_fn1: prior value of F1 (Hz) t_fn2: prior value of F2 (Hz) If cepsWinWidth is <= 0, cepstral liftering will be disabled. */ LPFormantTracker::LPFormantTracker(const int t_nLPC, const int t_sr, const int t_bufferSize, const int t_nFFT, const int t_cepsWinWidth, const int t_nTracks, const dtype t_aFact, const dtype t_bFact, const dtype t_gFact, const dtype t_fn1, const dtype t_fn2, const bool t_bMWA, const int t_avgLen) : nLPC(t_nLPC), sr(t_sr), bufferSize(t_bufferSize), nFFT(t_nFFT), cepsWinWidth(t_cepsWinWidth), nTracks(t_nTracks), aFact(t_aFact), bFact(t_bFact), gFact(t_gFact), fn1(t_fn1), fn2(t_fn2), bMWA(t_bMWA), avgLen(t_avgLen) { /* Input sanity checks */ if ( (nLPC <= 0) || (bufferSize <= 0) || (nFFT <= 0) || (nTracks <= 0) ) throw initializationError(); if (nLPC > maxNLPC) throw nLPCTooLargeError(); bCepsLift = (cepsWinWidth > 0); winFunc = new dtype[bufferSize]; /* Initialize window */ genHanningWindow(); nLPC_SQR = nLPC * nLPC; Acompanion = new dtype[nLPC_SQR]; AHess = new dtype[nLPC_SQR]; temp_frame = new dtype[bufferSize + nLPC + 2]; // +2 for playing it safe! TODO: improve R = new dtype[nLPC * 2]; // *2 for playing it safe! TODO: improve /* Initalize FFT working date fields */ ftBuf1 = new dtype[nFFT * 2]; ftBuf2 = new dtype[nFFT * 2]; fftc = new dtype[nFFT * 2]; gen_w_r2(fftc, nFFT); /* Intermediate data fields */ lpcAi = new dtype[maxNLPC + 1]; realRoots = new dtype[maxNLPC]; imagRoots = new dtype[maxNLPC]; cumMat = new dtype[maxFmtTrackJump * maxNTracks]; costMat = new dtype[maxFmtTrackJump * maxNTracks]; nCands = 6; /* number of possible formant candiates (should be > ntracks but < p.nLPC/2!!!! (choose carefully : not fool-proof) TODO: Implement automatic checks */ weiMatPhi = new dtype[nTracks * maxAvgLen]; weiMatBw = new dtype[nTracks * maxAvgLen]; weiVec = new dtype[maxAvgLen]; sumWeiPhi = new dtype[nTracks]; sumWeiBw = new dtype[nTracks]; trackFF = 0.95; radius_us = new dtype[maxNLPC]; /* TODO: Tighten the size */ phi_us = new dtype[maxNLPC]; bandwidth_us = new dtype[maxNLPC]; //phi_s = new dtype[maxNLPC]; /* Call reset */ reset(); }