4

OS XのリニアPCMオーディオファイル(複数のオーディオチャネルが含まれる可能性があります)でFFTを実行しようとしています。これを実行するための最良の方法は何ですか?

いくつかの情報源は、AppleのAccelerateFrameworkが私に必要なものであることを示しています。もしそうなら、それらのFFT関数で使用するために浮動小数点データをどのように抽出して適切に準備する必要がありますか?

4

3 に答える 3

7

やりたいことは大体こんな感じ。独自の入力関数と出力関数を入力します。

    // Stick new data into inData, a (float*) array
    fetchFreshData(inData); 

    // (You might want to window the signal here... )
    doSomeWindowing(inData);

    // Convert the data into a DSPSplitComplex 
    // Pardon the C++ here. Also, you should pre-allocate this, and NOT
    // make a fresh one each time you do an FFT. 
    mComplexData = new DSPSplitComplex;
    float *realpart = (float *)calloc(mNumFrequencies, sizeof(float));
    float *imagpart = (float *)calloc(mNumFrequencies, sizeof(float));
    mComplexData->realp = realpart;
    mComplexData->imagp = imagpart;

    vDSP_ctoz((DSPComplex *)inData, 2, mComplexData, 1, mNumFrequencies);

    // Calculate the FFT
    // ( I'm assuming here you've already called vDSP_create_fftsetup() )
    vDSP_fft_zrip(mFFTSetup, mComplexData, 1, log2f(mNumFrequencies), FFT_FORWARD);

    // Don't need that frequency
    mComplexData->imagp[0] = 0.0;

    // Scale the data
    float scale = (float) 1.0 / (2 * (float)mSignalLength);
    vDSP_vsmul(mComplexData->realp, 1, &scale, mComplexData->realp, 1, mNumFrequencies);
    vDSP_vsmul(mComplexData->imagp, 1, &scale, mComplexData->imagp, 1, mNumFrequencies);

    // Convert the complex data into something usable
    // spectrumData is also a (float*) of size mNumFrequencies
    vDSP_zvabs(mComplexData, 1, spectrumData, 1, mNumFrequencies);

    // All done!
    doSomethingWithYourSpectrumData(spectrumData);

それが役立つことを願っています。

于 2010-10-28T01:57:58.253 に答える
3

オーディオ データに対して FFT を実行する場合、サンプルは実数部分に入り、虚数部分はゼロになるはずです。

Apple の vDSP を含むほとんどの FFT ライブラリには、入力が実数 (虚数成分なし) で出力が複素数である「実数 FFT」と呼ばれる方法が含まれています。

于 2009-12-30T08:55:14.863 に答える
0

Core Audio を調べる必要があるように思えます... 私はそれにあまり詳しくありませんが、チャネルのインターリーブ解除が既に行われているようで、PCM データで直接動作します。あまり詳しくないので、これは大まかに考えてください。ただし、FFT を Audio Unit に入れ、単一チャネルの PCM データを入力として取り、FFT の結果をアクセス可能な場所に保存し、入力を渡してみます。アウトプットまで。

実際に FFT を実行する限り、主な課題は、FFT ルーチンが操作したい double * ベクトルに PCM 入力を強制することにあるように思えます。vDSP.h (加速フレームワークの一部) を見ると、vDSP_vflt16D (16 ビット整数のベクトルを倍精度実数のベクトルに変換する) のような関数が表示され、問題が解決するようです。

コアオーディオの紹介

于 2009-12-27T04:30:40.510 に答える