This is DSPFFTFrequency.m in view mode; [Download] [Up]
/* DSPFFTFrequency.m -- copyright 1992, 1993, 1994 by C.D.Lane */ #import <musickit/musickit.h> #import <dsp/arrayproc.h> #import "DSPFFTFrequency.h" #define FFT_SIZE (1024) #define FREQ_ADJUST (2) #define FFT_DATA DSPAPGetLowestAddressXY() #define FFT_COEF (FFT_DATA + FFT_SIZE) #define FFT_IMAG DSPMapPMemY(FFT_DATA) #define FFT_REAL DSPMapPMemX(FFT_DATA) #define SIN_TABLE DSPMapPMemY(FFT_COEF) #define COS_TABLE DSPMapPMemX(FFT_COEF) typedef enum {LINEAR = -1, INDEXED = 0} ADDR_MODES; @implementation DSPFFTFrequency : Frequency - init { #ifdef DEBUG (void) DSPSetErrorFP(stderr); (void) DSPEnableErrorLog(); #endif return [super init]; } - free { #ifdef DEBUG (void) DSPDisableErrorLog(); #endif return [super free]; } - (double) computeFrequency:sample { unsigned int i; MKKeyNum note, maximum = c00k; double pitch, power, pitches[c7k], hits[c7k]; short data[FFT_SIZE], *pointer = (short *) [(Sound *) sample data]; float spectrum[FFT_SIZE], rate = ([sample samplingRate] / FREQ_ADJUST) / FFT_SIZE; if([sample sampleCount] < (FFT_SIZE * FREQ_ADJUST)) return FREQUENCY_UNSTABLE; for(i = 0; i < FFT_SIZE; i++) data[i] = pointer[i * FREQ_ADJUST]; for(note = c00k; note < b6k; note++) pitches[note] = hits[note] = 0.0; if(DSPAPInit() == 0) { (void) DSPAPWriteFloatArray(DSPAPSinTable(FFT_SIZE), SIN_TABLE, 1, FFT_SIZE/2); (void) DSPAPWriteFloatArray(DSPAPCosTable(FFT_SIZE), COS_TABLE, 1, FFT_SIZE/2); (void) DSPAPWriteShortArray(data, FFT_REAL, 1, FFT_SIZE); (void) DSPAPvclear(FFT_IMAG, 1, FFT_SIZE); (void) DSPAPfftr2a(FFT_SIZE, FFT_DATA, FFT_COEF); (void) DSPSetDMAReadMReg(INDEXED); { (void) DSPAPReadFloatArray(spectrum, FFT_IMAG, FFT_SIZE/2, FFT_SIZE); } (void) DSPSetDMAReadMReg(LINEAR); (void) DSPAPFree(); } else return FREQUENCY_ERROR; for(i = 0; i < ((FFT_SIZE/2)/FREQ_ADJUST); i++) { note = MKFreqToKeyNum(pitch = (i * rate), NULL, 0.0); hits[note] += (power = fabs(spectrum[i])); pitches[note] += (pitch * power); } for(note = c00k; note < b6k; note++) if(hits[note] > hits[maximum]) maximum = note; if(hits[maximum] == 0.0) return FREQUENCY_UNSTABLE; return pitches[maximum] / hits[maximum]; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.