Ios 如何获得频率量级的FFT结果?
我使用以下代码(基于苹果的audioRouch示例): 在最简单的-1Hz正弦波上计算FFT(上移1个单位):Ios 如何获得频率量级的FFT结果?,ios,iphone,signal-processing,fft,accelerate-framework,Ios,Iphone,Signal Processing,Fft,Accelerate Framework,我使用以下代码(基于苹果的audioRouch示例): 在最简单的-1Hz正弦波上计算FFT(上移1个单位): Float32 wavereq=1.0; int samplesCount=1024; 浮动32个样本秒=1000//采样率 Float32 dt=1/样本秒; Float32 sd=M_PI*2.0*WaveReq; FFTHelper*mFFTHelper=新FFTHelper(样本计数); Float32 NyquistMaxFreq=samplesPerSecond/2.0;
Float32 wavereq=1.0;
int samplesCount=1024;
浮动32个样本秒=1000//采样率
Float32 dt=1/样本秒;
Float32 sd=M_PI*2.0*WaveReq;
FFTHelper*mFFTHelper=新FFTHelper(样本计数);
Float32 NyquistMaxFreq=samplesPerSecond/2.0;
Float32 fftDataSize=样本计数/2.0;
Float32*sinusoidOriginal=(Float32*)malloc(sizeof(Float32)*样本计数);
Float32*outFFTData=(Float32*)malloc(sizeof(Float32)*fftDataSize);
// 2. 生成sin样本:
对于(int i=0;iComputeFFT(原始,输出数据);
对于(int i=0;i
我得到的结果是:
黑线是FTT的绘图仪结果,以其频率水平放置。
DC值(左侧第一条黑线)看起来正常,正确表示y=sin(x)+1垂直偏移
但是为什么代表窦房结方程中唯一频率的第二条黑线,没有幅值=1,也没有精确地保持在1Hz?
有人能给我指一下vDSP函数,将FFT结果从输入信号转换成幅度单位吗?简短回答: 你似乎在使用我在这里回答的代码: 很好,但是: 你无法在你的信号中避免这些额外的频率 你产生的信号(正弦波)是一个无限信号。 若你们“裁剪它”并且“只使用一段信号”,它会在两端引入“削波噪声” 但是,您可以通过在FFT之前获取更大的输入块来最小化噪声。Accelerate框架提供了一些良好且简单的窗口功能。(例) 另外-使用较大的输入块。输入越大,频率检测越精确 请参阅,谷歌:光谱泄漏,窗口功能
void FFTHelper::ComputeFFT(Float32* inAudioData, Float32* outFFTData)
{
if (inAudioData == NULL || outFFTData == NULL) return;
// Generate a split complex vector from the real data
vDSP_ctoz((COMPLEX *)inAudioData, 2, &mDspSplitComplex, 1, mFFTLength);
// Take the fft and scale appropriately
vDSP_fft_zrip(mSpectrumAnalysis, &mDspSplitComplex, 1, mLog2N, kFFTDirection_Forward);
vDSP_vsmul(mDspSplitComplex.realp, 1, &mFFTNormFactor, mDspSplitComplex.realp, 1, mFFTLength);
vDSP_vsmul(mDspSplitComplex.imagp, 1, &mFFTNormFactor, mDspSplitComplex.imagp, 1, mFFTLength);
// Zero out the nyquist value
mDspSplitComplex.imagp[0] = 0.0;
// Complex vector magnitudes squared; single precision.
// Calculates the squared magnitudes of complex vector A.
vDSP_zvmags(&mDspSplitComplex, 1, outFFTData, 1, mFFTLength);
}
Float32 waveFreq = 1.0;
int samplesCount = 1024;
Float32 samplesPerSecond = 1000; //sample rate
Float32 dt = 1 / samplesPerSecond;
Float32 sd = M_PI * 2.0 * waveFreq;
FFTHelper *mFFTHelper = new FFTHelper(samplesCount);
Float32 NyquistMaxFreq = samplesPerSecond/2.0;
Float32 fftDataSize = samplesCount/2.0;
Float32 *sinusoidOriginal = (Float32 *)malloc(sizeof(Float32) * samplesCount);
Float32 *outFFTData = (Float32 *)malloc(sizeof(Float32) * fftDataSize);
// 2. Generate sin samples:
for (int i = 0; i < samplesCount; i++) {
Float32 x = dt * i;
sinusoidOriginal[i] = sin(sd * x) + 1;
[originalPlot addVector2D:GLVector2DMake(x, sinusoidOriginal[i])];
}
mFFTHelper->ComputeFFT(sinusoidOriginal, outFFTData);
for (int i = 0; i < fftDataSize; i++) {
Float32 hz = ((Float32)i / (Float32)fftDataSize) * NyquistMaxFreq;
GLfloat mag = outFFTData[i];
[fftPlot addVector2D:GLVector2DMake(hz, 0)];
[fftPlot addVector2D:GLVector2DMake(hz, mag)];
}