gpt4 book ai didi

objective-c - 使用EZAudio进行FFT获得更精确的频率?

转载 作者:行者123 更新时间:2023-12-02 23:04:26 25 4
gpt4 key购买 nike

我生成了一些带有不同频率的Audacity的纯正弦音色进行测试。我看到的问题是,对于值相对接近的两个不同的正弦音,代码返回的频率相同。

例如:在19255Hz处产生的正弦音将从FFT显示为19293.750000Hz。因此会以19330Hz产生正弦音。

低频和高频都有同样的问题...例如93hz在FFT中会显示为96.899414hz

计算中必须关闭某些内容。缓冲区大小为4096。

非常感谢您提供有关如何修改上述代码以获取更精确的FFT频率(纯正弦音)的帮助。谢谢!

//
// 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];

float nyquistMaxFreq = self.sampleRate / 2.0;
NSLog(@"FREQ: %f", (((float)self.info->maxFrequencyIndex / (float)self.info->outFFTDataLength) * nyquistMaxFreq));

}

此处的EZAudio代码: https://github.com/syedhali/EZAudio/blob/master/EZAudio/EZAudioFFT.m

最佳答案

您仅查看一个幅度FFT结果仓的频率,该频率仓将频率量化为dF = sample_rate / N。您可以使用较大的N(较长的FFT)来获得较小的量化。在低噪声和低干扰的情况下,将采样数据零填充以允许更长的FFT可能会提高绘图分辨率。

为了获得更好的频率估计,您必须使用开窗Sinc插值法以及可能的逐次逼近方法在FFT结果仓之间进行估计,以找到最接近最大幅度FFT结果仓的频谱频率峰值。

关于objective-c - 使用EZAudio进行FFT获得更精确的频率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48082946/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com