/* FFTFrequency.m -- copyright 1992, 1993, 1994 by C.D.Lane */

#import "FFTFrequency.h"
#import "libfft.h"

@implementation FFTFrequency : Frequency

- init
{
	initfft(LOG2_FFTSIZE);

	return self;
}

- (double) computeFrequency:sample
{
	unsigned int i;
	double pitch, power;
	MKKeyNum note, maximum = c00k;
	short *pointer = (short *) [(Sound *) sample data];

	rate = [sample samplingRate] / FFT_SIZE;

	if([sample sampleCount] < FFT_SIZE) return FREQUENCY_UNSTABLE;

	for(i = 0; i < FFT_SIZE; i++) {
		real[i] = pointer[i];
		imaginary[i] = 0;
		}

	for(note = c00k; note < b7k; note++) pitches[note] = hits[note] = 0.0;

	fft(real, imaginary, FALSE);

	for(i = 0; i < (FFT_SIZE/2); i++) {
		note = MKFreqToKeyNum(pitch = (i * rate), NULL, 0.0);
		pitch += (MKKeyNumToFreq(note) - (rate * floor(MKKeyNumToFreq(note) / rate))) / 2;
		hits[note] += (power = fabs(imaginary[i]));
		pitches[note] += (pitch * power);
		}

	for(note = c00k; note < b7k; note++) if(hits[note] > hits[maximum]) maximum = note;

	if(hits[maximum] == 0) return FREQUENCY_UNSTABLE;

	return pitches[maximum] / hits[maximum];
}

- (double) toleranceAtFrequency:(double) freq;
{
	return(rate / freq);
}

@end
