[Scopeapp-cvs]scopeapp/src SpectrumView.h,1.8,1.9 SpectrumView.m,1.13,1.14
Status: Alpha
Brought to you by:
narge
From: <sco...@li...> - 2003-02-20 02:23:01
|
Update of /cvsroot/scopeapp/scopeapp/src In directory sc8-pr-cvs1:/tmp/cvs-serv1302/src Modified Files: SpectrumView.h SpectrumView.m Log Message: Implemented several windowing functions (Bartlett, Blackman, Hamming, Hann (aka Hanning), Welch). Change scaling again; FFT results are divided by the area of the window function (which is N for the rectangular window). Index: SpectrumView.h =================================================================== RCS file: /cvsroot/scopeapp/scopeapp/src/SpectrumView.h,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** SpectrumView.h 19 Feb 2003 06:08:43 -0000 1.8 --- SpectrumView.h 20 Feb 2003 02:22:58 -0000 1.9 *************** *** 37,40 **** --- 37,45 ---- typedef enum WindowType { eWindowRectangular = 0, + eWindowBartlett, + eWindowHann, + eWindowHamming, + eWindowBlackman, + eWindowWelch, } WindowType; *************** *** 83,86 **** --- 88,92 ---- NSData* myWindowFactors; WindowType myWindowType; + float myWindowArea; NSLock* mySavedDataLock; } Index: SpectrumView.m =================================================================== RCS file: /cvsroot/scopeapp/scopeapp/src/SpectrumView.m,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** SpectrumView.m 19 Feb 2003 11:01:26 -0000 1.13 --- SpectrumView.m 20 Feb 2003 02:22:58 -0000 1.14 *************** *** 114,117 **** --- 114,119 ---- myFFTSetup = create_fftsetup(log2n, kFFTRadix2); + [self recalculateWindowWithSize: n]; + if(wasDrawing) [self startDrawing]; } else { *************** *** 214,218 **** // apply scaling factor ! scale = 1.0 / length; vsmul(real, 1, &scale, real, 1, length / 2); vsmul(imag, 1, &scale, imag, 1, length / 2); --- 216,224 ---- // apply scaling factor ! // I'm not sure that this is correct, but it gives correct results for ! // a wave with a power of 2 number of samples per cycle and ! // approximately correct (better than rectangular window) results for ! // other frequencies. ! scale = 1.0 / myWindowArea; vsmul(real, 1, &scale, real, 1, length / 2); vsmul(imag, 1, &scale, imag, 1, length / 2); *************** *** 253,257 **** --- 259,270 ---- int i, count = [data length] / sizeof(float); + if(myWindowFactors == nil || + [data length] != [myWindowFactors length]) + { + [self recalculateWindowWithSize: count]; + } + if(myWindowType == eWindowRectangular) { + // take a shortcut... return data; } *************** *** 259,271 **** newData = malloc([data length]); oldData = [data bytes]; [mySavedDataLock lock]; - if([data length] != [myWindowFactors length]) - { - [self recalculateWindowWithSize: count]; - } - factors = [myWindowFactors bytes]; - #ifdef __APPLE__ #pragma unused(i) --- 272,279 ---- newData = malloc([data length]); oldData = [data bytes]; + factors = [myWindowFactors bytes]; [mySavedDataLock lock]; #ifdef __APPLE__ #pragma unused(i) *************** *** 570,573 **** --- 578,582 ---- { float* data; + int i; if(myWindowFactors != nil) { *************** *** 577,587 **** --- 586,633 ---- if(myWindowType == eWindowRectangular) { myWindowFactors = nil; + myWindowArea = length; return self; } data = malloc(length * sizeof(float)); + myWindowArea = 0; switch(myWindowType) { + case eWindowBartlett: + for(i=0; i<length/2; i++) { + data[i] = (2.0 * i) / (length - 1); + myWindowArea += data[i]; + } + for(i=length/2; i<length; i++) { + data[i] = (2.0 * (length - i - 1)) / (length - 1); + myWindowArea += data[i]; + } + break; + case eWindowHann: + for(i=0; i<length; i++) { + data[i] = 0.5 * (1 - cos(2*M_PI*((float)i / (length - 1)))); + myWindowArea += data[i]; + } + break; + case eWindowHamming: + for(i=0; i<length; i++) { + data[i] = 0.54 - (0.46*cos(2*M_PI*((float)i / (length - 1)))); + myWindowArea += data[i]; + } + break; + case eWindowBlackman: + for(i=0; i<length; i++) { + data[i] = 0.42 - (0.5*cos(2*M_PI*((float)i / (length - 1)))) + + (0.08*cos(4*M_PI*((float)i / (length - 1)))); + myWindowArea += data[i]; + } + break; + case eWindowWelch: + for(i=0; i<length; i++) { + data[i] = 1 - pow(((float)i - (length/2))/(length/2), 2); + myWindowArea += data[i]; + } + break; default: NSLog(@"-[SpectrumView recalculateWindowWithSize:]: unknown window type"); |