Kiss FFT bin幅度

| 我已经花了很多时间研究FFT。使用KISSFFT尤其使我感兴趣,因为它是一种非常可移植的C实现。 我仍然不清楚如何将i [x]和r [x]转换为频率仓的幅度。因此创建了一个带符号的int 16版本的sin。我有512个罪恶样本。我希望看到一个Bin带有数据,其余的为零。不是啊 这是我的代码...
- (IBAction)testFFT:(id)sender{
NSLog(@\"testFFT\");

static double xAxis = 0;
static int sampleCount = 0;
static double pieSteps;
static double fullSinWave = 3.14159265*2;
static double sampleRate = 44100;
static double wantedHz = 0;
int octiveOffset;
char * globalString = stringToSend;
SInt16 dataStream[512];

// Notes: ioData contains buffers (may be more than one!)
// Fill them up as much as you can. Remember to set the size value in each buffer to match how
// much data is in the buffer.
for (int j = 0; j < 512; j++) {
    wantedHz = 1000;
    pieSteps = fullSinWave/(sampleRate/wantedHz);
    xAxis += pieSteps; 
    dataStream[j] = (SInt16)(sin(xAxis) * 32768.0);
    NSLog(@\"%d) %d\", j, dataStream[j]);
}

kiss_fft_cfg mycfg = kiss_fft_alloc(512,0,NULL,NULL);
kiss_fft_cpx* in_buf = malloc(sizeof(kiss_fft_cpx)*512);
kiss_fft_cpx* out_buf = malloc(sizeof(kiss_fft_cpx)*512);
for (int i = 0;i < 512;i++){
    in_buf[i].r = dataStream[i];
    in_buf[i].i = dataStream[i];
}    
kiss_fft(mycfg,in_buf, out_buf);
for (int i = 0;i < 256;i++){
    ix = out_buf[i].i;
    rx = out_buf[i].r;
    printfbar(sqrt(ix*ix+rx*rx)););
}
} 我得到的结果看起来像这样... ***** ********************* **************************** ********************* ************************ ********************* **************************** ********************* ***** ********************* **************************** ********************* ***************** ********************* **************************** ********************* ***** ********************* **************************** ********************* ************************ ********************* **************************** *********************     
已邀请:
        首先进行一些编程更改:
xAxis += pieSteps;
if (xAxis >= fullSinWave)
  xAxis -= fullSinWave; //wrap x back into 0-2pi period
将有助于减少数字错误。
in_buf[i].r = dataStream[i];
in_buf[i].i = 0;
会将输入缓冲区设置为
sin(x)
,之前您已将其设置为ѭ4where,其中
j = sqrt(-1)
。 将
wantedHz = 1000;
移出循环看起来更好。 还有一个更基本的问题:您设置
wantedHz = 1000
。采样率为44.1 kHz时,相当于
44100 points/sec * (1/1000) sec/cycle = 44.1 points/cycle
。使用512点的缓冲区,您将在缓冲区中获得11.6个正弦波周期。非整数周期会导致泄漏。 但是,在进行此设置之前,尝试将ѭ9设置为正好在缓冲区中提供12个周期。您应该在变换中看到两个峰值:一个在索引12,一个在索引511-12。 您会看到两个峰值的原因是
sin(w_0*x)
的变换是
j*{-delta(w-w_0) - delta(w+w_0)}
。也就是说,在变换的虚部,您在w_0和-w_0处获得了脉冲函数。它们之所以在原处,是因为变换从0变为2 * pi。 执行完此操作后,返回
wantedH = 1000
,缓冲区中的循环数为非整数。您应该看到一个以帐篷11和511-11为中心的宽帐篷形结果。您应将
dataStream
乘以窗口函数(Hann很好),以减少此效果的影响。     
        我也一直在和这个库打架,这段代码可以帮助您测试。我在Internet上阅读了混合的代码,看看是否可以将其包含在项目中。工作良好。它也要写入文件,其中包含原始信号,FFT和逆FFT的波形和值。它是用VS2010编译的
#include \"kiss_fft.h\"
#include \"tools\\kiss_fftr.h\"
#include <stdio.h>
#include <conio.h>
#define numberOfSamples 1024

int main(void)
{
    struct KissFFT
    {
            kiss_fftr_cfg forwardConfig;
            kiss_fftr_cfg inverseConfig;
            kiss_fft_cpx* spectrum;
            int numSamples;
            int spectrumSize;
    } fft;

    static double dospi = 3.14159265*2;
    static double sampleRate = 44100;
    static double wantedHz = 0;
    int j,i,k;
    float dataStream[numberOfSamples];
    float dataStream2[numberOfSamples];
    float mags[numberOfSamples];
    FILE * pFile;

    //Frequency to achive
    wantedHz = 9517;

    fft.forwardConfig = kiss_fftr_alloc(numberOfSamples,0,NULL,NULL);
    fft.inverseConfig = kiss_fftr_alloc(numberOfSamples,1,NULL,NULL);
    fft.spectrum = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * numberOfSamples);
    fft.numSamples = numberOfSamples;
    fft.spectrumSize = numberOfSamples/2+1;


    pFile = fopen (\"c:\\\\testfft.txt\",\"w\");
    //filling the buffer data with a senoidal wave of frequency -wantedHz- and printing to testing it
    for (j = 0; j < numberOfSamples; j++) {

            dataStream[j] = 32768*(sin(wantedHz*dospi*j/sampleRate));
            //Draw the wave form 
            for (k=-64;k<(int)(dataStream[j]/512);k++)  fprintf(pFile,\" \");
            fprintf(pFile,\"*\\n\");
    }

    //spectrum
    kiss_fftr(fft.forwardConfig, dataStream, fft.spectrum);
    //inverse just to testing
    kiss_fftri( fft.inverseConfig, fft.spectrum, dataStream2 );
    for(i=0;i<fft.spectrumSize;i++) {
        mags[i] = hypotf(fft.spectrum[i].r,fft.spectrum[i].i);
        fprintf(pFile,\"[Sample %3d] ORIGINAL[%6.0f]   -SPECTRUM[%5dHz][%11.0f]\",i,dataStream[i],i*(int)sampleRate/numberOfSamples,mags[i]);
        dataStream2[i] = dataStream2[i] / (float)fft.numSamples;
        fprintf(pFile,\"     -INVERSE[%6.0f]\\n\",dataStream2[i]);
    }
    //end

    //free and close
    fclose (pFile);
    kiss_fft_cleanup();   
    free(fft.forwardConfig);
    free(fft.inverseConfig);
    free(fft.spectrum);

    getch();
    return 0;
}     

要回复问题请先登录注册