0

これはstackoverflowに関する私の最初の質問であり、残念ながら私の英語は貧弱です。でもやってみたい。

Kissfft の twotonetest のカスタマイズされたルーチンは、2 つの異なるシステムで非常に異なる結果をもたらします。

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 に答える