#include "analysistransform.h" // Create a constructor for analysis transform analysistransform::analysistransform() { this->signallength = 20480; this->windowsize = 2048; this->overlap = 1024; this->nofmics = 32; int lngth = (windowsize / 2 + 1) * (signallength / (overlap)); outputsignal = (std::complex *) malloc(sizeof(std::complex ) * lngth); } // Create a constructor for analysis transform analysistransform::analysistransform(int windowsize=2048, int signallength=20480, int hopsize=1024,int nofmics=32) { this->signallength = signallength; this->windowsize = windowsize; this->overlap = hopsize; this->nofmics = nofmics; int lngth = (windowsize / 2 + 1) * (signallength / (hopsize)); outputsignal = (std::complex *) malloc(sizeof(std::complex ) * lngth); } // Create a hamming window of windowLength samples in buffer void analysistransform::hamming(int windowLength, float* buffer) { for (int i = 0; i < windowLength; i++) { buffer[i] = 0.54 - (0.46 * cos(2 * PI * (i / ((windowLength - 1) * 1.0)))); } } /* Signal in : x[0] to x[signalLength - 1] realpart : fft_real[0] to fft_real[N/2 -1] imagpart : imagpart[0] to imagpart[N/2 -1] */ void* analysistransform::STFT(float* signal, float* realpart, float* imagpart) { double* data; fftw_complex* fft_result; fftw_plan plan_forward, plan_backward; int i; data = (double*)fftw_malloc(sizeof(double) * this->windowsize); fft_result = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * this->windowsize); int outputcounter = 0; plan_forward = fftw_plan_dft_r2c_1d(this->windowsize, data, fft_result, FFTW_ESTIMATE); // Create a hamming window of appropriate length float* window = (float*)malloc(sizeof(float) * this->windowsize); hamming(this->windowsize, window); int chunkPosition = 0; int readIndex; // Should we stop reading in chunks? int bStop = 0; // Process each chunk of the signal while (chunkPosition < this->signallength && !bStop) { // Copy the chunk into our buffer for (i = 0; i < this->windowsize; i++) { readIndex = chunkPosition + i; if (readIndex < this->signallength) { // 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. fftw_destroy_plan(plan_forward); fftw_free(data); fftw_free(fft_result); free(window); return 0; }