#include "analysistransform.h" // Create a constructor for analysis transform analysistransform::analysistransform() { this->signallength = 20480; this->windowsize = 2048; this->overlap = 1024; this->nofmics = 32; // Create a hamming window of appropriate length window = (double*)malloc(sizeof(double) * this->windowsize); hamming(this->windowsize, window); } // Create a constructor for analysis transform analysistransform::analysistransform(int windowsize, int signallength, int hopsize,int nofmics) { this->signallength = signallength; this->windowsize = windowsize; this->overlap = hopsize; this->nofmics = nofmics; // Create a hamming window of appropriate length window = (double*)malloc(sizeof(double) * this->windowsize); hamming(this->windowsize, window); } // Create a hamming window of windowLength samples in buffer void analysistransform::hamming(int windowLength, double* buffer) { for (int i = 0; i < windowLength; i++) { buffer[i] = 0.54 - (0.46 * cos(2 * PI * (i / (((double)windowLength - 1.0) * 1.0)))); } } /* Signal in : x[0] to x[signalLength - 1] nofmics : the number of the microphones realpart : fft_real[0] to fft_real[N/2 -1] imagpart : imagpart[0] to imagpart[N/2 -1] */ void* analysistransform::FFT(double* signal, double* realpart, double* imagpart) { double* data; fftw_complex* fft_result; fftw_plan plan_forward; int i; data = (double*)fftw_malloc(sizeof(double) * this->windowsize); fft_result = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * this->windowsize); plan_forward = fftw_plan_dft_r2c_1d(this->windowsize, data, fft_result, FFTW_ESTIMATE); int readIndex; // Should we stop reading in chunks? int bStop = 0; int channelindex = 0; // Process each chunk of the signal for (channelindex = 0; channelindex < this->nofmics; channelindex++) { int outputcounter = channelindex; int chunkPosition = 0; while (chunkPosition < this->signallength && !bStop) { // Copy the chunk into our buffer for (i = 0; i < this->windowsize; i++) { readIndex = (chunkPosition + i) * this->nofmics + channelindex; if (readIndex < this->signallength * this->nofmics) { // Note the windowing! data[i] = signal[readIndex] * window[i]; } else { // we have read beyond the signal, so zero-pad it! data[i] = 0.0; bStop = 1; } } // Perform the FFT on our chunk fftw_execute(plan_forward); // Copy the first (windowSize/2 + 1) data points into your spectrogram. // We do this because the FFT output is mirrored about the nyquist // frequency, so the second half of the data is redundant. This is how // Matlab's spectrogram routine works. for (i = 0; i < this->windowsize / 2; i++) { *(realpart + outputcounter) = fft_result[i][0]; *(imagpart + outputcounter) = fft_result[i][1]; outputcounter += this->nofmics; } chunkPosition += this->overlap; } // Excuse the formatting, the while ends here. bStop = 0; } fftw_destroy_plan(plan_forward); fftw_free(data); fftw_free(fft_result); return 0; }