Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/117.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何获得频率量级的FFT结果?_Ios_Iphone_Signal Processing_Fft_Accelerate Framework - Fatal编程技术网

Ios 如何获得频率量级的FFT结果?

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;

我使用以下代码(基于苹果的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 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)];

    }