0

这是我关于stackoverflow的第一个问题,不幸的是我的英语很差。但我想试试。

Kissfft 的 twotonetest 的定制例程带来了两个不同的系统非常不同的结果。

在 x86 程序上用 gcc 翻译的 ubuntu 下会带来正确的值。使用为 Arduino YUN (Atheros AR9331) 程序翻译的 openWRT SDK 显示不正确的值​​​。似乎因为 FIXED_POINT 的定义被忽略了。

定义为:

#define FIXED_POINT 32

功能:

double GetFreqBuf( tBuf * io_pBuf, int nfft)
{
    kiss_fftr_cfg cfg   = NULL;
    kiss_fft_cpx *kout  = NULL;
    kiss_fft_scalar *tbuf = NULL;
    uint32_t ptr;
    int i;
    double sigpow=0;
    double noisepow=0;
    long maxrange = SHRT_MAX;

    cfg = kiss_fftr_alloc(nfft , 0, NULL, NULL);
    tbuf    = KISS_FFT_MALLOC(nfft * sizeof(kiss_fft_scalar));
    kout    = KISS_FFT_MALLOC(nfft * sizeof(kiss_fft_cpx));

    /* generate the array from samples*/
    for (i = 0; i < nfft; i++) {

        //nur einen Kanal, eine Krücke, würde nun auch mit 2 kanälen gehen, aber so ist schneller
        if (io_pBuf->IndexNextValue >= (i*2))
            ptr = io_pBuf->IndexNextValue - (i*2);
        else
            ptr = io_pBuf->bufSize  - ((i*2) - io_pBuf->IndexNextValue);
         tbuf[i] = io_pBuf->aData[ptr] ;
    }

    kiss_fftr(cfg, tbuf, kout);

    for (i=0;i < (nfft/2+1);++i) {
        double tmpr = (double)kout[i].r / (double)maxrange;
        double tmpi = (double)kout[i].i / (double)maxrange;
        double mag2 = tmpr*tmpr + tmpi*tmpi;
        if (i!=0 && i!= nfft/2)
            mag2 *= 2; /* all bins except DC and Nyquist have symmetric counterparts implied*/

        /* if there is power between the frq's, it is signal, otherwise noise*/
        if ( i > nfft/96 && i < nfft/32 )
            noisepow += mag2;
        else
            sigpow += mag2;
    }

    kiss_fft_cleanup();
    //printf("TEST %d Werte, noisepow: %f sigpow: %f noise @ %fdB\n",nfft,noisepow,sigpow,10*log10(noisepow/sigpow +1e-30) );
   free(cfg);
   free(tbuf);
   free(kout);
    return 10*log10(noisepow/sigpow +1e-30);
}

使用来自同一文件的 16 位声音的输入样本。结果不同,例如从-3dB 到-15dB。A您可以从哪里开始进行故障排除?

4

1 回答 1

0

可能性#1(最有可能)

您编译的 Kissfft.c 或 Kiss_fftr.c 与调用代码不同。这发生在很多人身上。

强制使用相同 FIXED_POINT 的一种简单方法是直接编辑 Kiss_fft.h。另一种选择:通过一些 printf 调试进行验证。即在不同的地方放置以下内容:

printf( __FILE__ " sees sizeof(kiss_fft_scalar)=%d\n" , sizeof(kiss_fft_scalar) )

可能性 #2

也许 FIXED_POINT=16 代码有效,但 FIXED_POINT=32 代码不起作用,因为在 Kissfft 内部或平台上处理不正确。32 位固定代码依赖于正确实现的 int64_t。

Atheros 是 16 位处理器吗?我知道 Kissfft 已在 16 位平台上成功使用,但我不确定是否已在 16 位定点上使用FIXED_POINT=32真实FFT。

维尔·格吕克,马克

于 2014-03-19T17:20:26.963 回答