You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've generated a few pure sine tones with Audacity at different frequencies to test with. The issue I'm seeing is that the code is returning the same frequency for two different sine tones that are relatively close in value.
For example: A sine tone generated at 19255Hz will show up from FFT as 19293.750000Hz. So will a sine tone generated at 19330Hz. Something must be off in the calculations.
Any assistance in how I can modify the above code to get a more precise FFT frequency reading for pure sine tones is greatly appreciated. Thank you!
I would guess that this issue is a result of the use of FFT. It quantizes the frequencies into bins (log2n is effectively the number of bins in the example). If you need more frequency resolution, you can try weighing the bins around the loudest bin according to their energies or use another algorithm.
I've generated a few pure sine tones with Audacity at different frequencies to test with. The issue I'm seeing is that the code is returning the same frequency for two different sine tones that are relatively close in value.
For example: A sine tone generated at 19255Hz will show up from FFT as 19293.750000Hz. So will a sine tone generated at 19330Hz. Something must be off in the calculations.
Any assistance in how I can modify the above code to get a more precise FFT frequency reading for pure sine tones is greatly appreciated. Thank you!
//
// Initialize FFT
//
float maximumBufferSizeBytes = self.maximumBufferSize * sizeof(float);
self.info = (EZAudioFFTInfo *)calloc(1, sizeof(EZAudioFFTInfo));
vDSP_Length log2n = log2f(self.maximumBufferSize);
self.info->fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);
long nOver2 = maximumBufferSizeBytes / 2;
size_t maximumSizePerComponentBytes = nOver2 * sizeof(float);
self.info->complexA.realp = (float *)malloc(maximumSizePerComponentBytes);
self.info->complexA.imagp = (float *)malloc(maximumSizePerComponentBytes);
self.info->outFFTData = (float *)malloc(maximumSizePerComponentBytes);
memset(self.info->outFFTData, 0, maximumSizePerComponentBytes);
self.info->inversedFFTData = (float *)malloc(maximumSizePerComponentBytes);
//
// Calculate real + imaginary components and normalize
//
vDSP_Length log2n = log2f(bufferSize);
long nOver2 = bufferSize / 2;
float mFFTNormFactor = 10.0 / (2 * bufferSize);
vDSP_ctoz((COMPLEX*)buffer, 2, &(self.info->complexA), 1, nOver2);
vDSP_fft_zrip(self.info->fftSetup, &(self.info->complexA), 1, log2n, FFT_FORWARD);
vDSP_vsmul(self.info->complexA.realp, 1, &mFFTNormFactor, self.info->complexA.realp, 1, nOver2);
vDSP_vsmul(self.info->complexA.imagp, 1, &mFFTNormFactor, self.info->complexA.imagp, 1, nOver2);
vDSP_zvmags(&(self.info->complexA), 1, self.info->outFFTData, 1, nOver2);
vDSP_fft_zrip(self.info->fftSetup, &(self.info->complexA), 1, log2n, FFT_INVERSE);
vDSP_ztoc(&(self.info->complexA), 1, (COMPLEX *) self.info->inversedFFTData , 2, nOver2);
self.info->outFFTDataLength = nOver2;
//
// Calculate max freq
//
if (self.sampleRate > 0.0f)
{
vDSP_maxvi(self.info->outFFTData, 1, &self.info->maxFrequencyMangitude, &self.info->maxFrequencyIndex, nOver2);
self.info->maxFrequency = [self frequencyAtIndex:self.info->maxFrequencyIndex];
}
EZAudio code here: https://github.com/syedhali/EZAudio/blob/master/EZAudio/EZAudioFFT.m
The text was updated successfully, but these errors were encountered: