Skip to content
This repository was archived by the owner on Jun 9, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions FFTManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,30 @@
#include "FFTManager.h"
#include<stdio.h>
#include <Accelerate/Accelerate.h>
#include <math.h>

struct FFTManager {
FFTSetup fftWeights;
float* multipliers;
};

void setupHammingWindow(float *values, int N) {
// The vdsp hamming window has the wrong divisor in the cosine argument, so
// we have to make our own hamming window.
for (int i = 0; i < N; ++i) {
values[i] = 0.54f - 0.46f * cosf(2.f*M_PI*i/(N-1));
}
}

FFTManager *createFFTManager(int sampleSize)
{
// assert(fmod(log2(sampleSize), 1.0) == 0.0); // sampleSize must be a power of 2

struct FFTManager *f;
f = (struct FFTManager*) malloc(sizeof(struct FFTManager));
f->fftWeights = vDSP_create_fftsetup(vDSP_Length(log2f(sampleSize)), FFT_RADIX2);
f->multipliers = (float*) malloc(sizeof(float) * sampleSize);
setupHammingWindow(f->multipliers, sampleSize);

return f;
}
Expand All @@ -33,11 +45,8 @@ void deleteFFTManager(FFTManager *fftManager)

void fft(FFTManager *manager, float * input, int inputSize, float *output)
{
// apply a hamming window to the input
float *hammingWindow = new float[inputSize];
vDSP_hamm_window(hammingWindow, inputSize, 0);
float *hammedInput = new float[inputSize]();
vDSP_vmul(input, 1, hammingWindow, 1, hammedInput, 1, inputSize);
vDSP_vmul(input, 1, manager->multipliers, 1, hammedInput, 1, inputSize);

// pack the input samples in preparation for FFT
float *zeroArray = new float[inputSize]();
Expand All @@ -47,8 +56,8 @@ void fft(FFTManager *manager, float * input, int inputSize, float *output)
vDSP_fft_zip(manager->fftWeights, &splitComplex, 1, log2f(inputSize), FFT_FORWARD);
vDSP_zvmags(&splitComplex, 1, output, 1, inputSize);

delete[](zeroArray);
delete[](hammingWindow);
delete[] zeroArray;
delete[] hammedInput;
}

void autocorrelation(float *input, int inputSize, float *output)
Expand Down Expand Up @@ -85,4 +94,4 @@ float dominantPower(float *input, int inputSize)
}

return dominantPower;
}
}
32 changes: 16 additions & 16 deletions FFTManager_fftw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@

struct FFTManager {
unsigned int N;
fftw_complex *in;
fftw_complex *out;
fftwf_complex *in;
fftwf_complex *out;
float* multipliers;
fftw_plan p;
fftwf_plan p;
};

void setupHammingWindow(float *values, int N) {
for (int i = 0; i < N; ++i) {
values[i] = 0.54 - 0.46 * cos(2*M_PI*i/(N-1));
values[i] = 0.54f - 0.46f * cosf(2.f*M_PI*i/(N-1));
}
}

FFTManager* createFFTManager(int sampleSize) {
FFTManager* _fft = (struct FFTManager*) malloc(sizeof(struct FFTManager));
_fft->N = sampleSize;
_fft->in = fftw_alloc_complex(sampleSize);
_fft->out = fftw_alloc_complex(sampleSize);
_fft->p = fftw_plan_dft_1d(sampleSize, _fft->in, _fft->out, FFTW_FORWARD, FFTW_MEASURE);
FFTManager* _fft = (struct FFTManager*) malloc(sizeof(struct FFTManager));
_fft->N = sampleSize;
_fft->in = fftwf_alloc_complex(sampleSize);
_fft->out = fftwf_alloc_complex(sampleSize);
_fft->p = fftwf_plan_dft_1d(sampleSize, _fft->in, _fft->out, FFTW_FORWARD, FFTW_MEASURE);

_fft->multipliers = (float*) malloc(sizeof(float) * sampleSize);
setupHammingWindow(_fft->multipliers, sampleSize);
_fft->multipliers = (float*) malloc(sizeof(float) * sampleSize);
setupHammingWindow(_fft->multipliers, sampleSize);

return _fft;
return _fft;
}

void fft(FFTManager *_fft, float * input, int inputSize, float *output) {
Expand All @@ -43,7 +43,7 @@ void fft(FFTManager *_fft, float * input, int inputSize, float *output) {
_fft->in[i][1] = 0.0;
}

fftw_execute(_fft->p);
fftwf_execute(_fft->p);

// Compute *squared* magnitudes
for (int i = 0; i <= _fft->N/2; ++i) {
Expand All @@ -52,9 +52,9 @@ void fft(FFTManager *_fft, float * input, int inputSize, float *output) {
}

void deleteFFTManager(FFTManager *_fft) {
fftw_destroy_plan(_fft->p);
fftw_free(_fft->in);
fftw_free(_fft->out);
fftwf_destroy_plan(_fft->p);
fftwf_free(_fft->in);
fftwf_free(_fft->out);
free(_fft);
}

Expand Down