14

更新2016-03-15

このプロジェクトをご覧ください:https ://github.com/ooper-shlab/aurioTouch2.0-Swift 。これはSwiftに移植されており、ここでカムした場合、探しているすべての答えが含まれています。


私は多くの調査を行い、FFTとAccelerateFrameworkについて多くを学びました。しかし、何日もの実験の後、私はちょっとイライラしています。

再生中のオーディオファイルの周波数スペクトルを図で表示したい。時間間隔ごとに、X軸のFFTによって計算されたすべての周波数(私の場合は512の値)のY軸(赤いバーで表示)に大きさをdbで表示する必要があります。

出力は次のようになります。 ここに画像の説明を入力してください

最初に左チャンネルのみを抽出する1024サンプルでバッファーを埋めます。それから私はこのすべてのFFTのことをします。

これまでの私のコードは次のとおりです。

いくつかの変数の設定

- (void)setupVars  
{  
    maxSamples = 1024;

    log2n = log2f(maxSamples);  
    n = 1 << log2n;  

    stride = 1;  
    nOver2 = maxSamples/2;  

    A.realp = (float *) malloc(nOver2 * sizeof(float));  
    A.imagp = (float *) malloc(nOver2 * sizeof(float));  
    memset(A.imagp, 0, nOver2 * sizeof(float));

    obtainedReal = (float *) malloc(n * sizeof(float));  
    originalReal = (float *) malloc(n * sizeof(float));

    setupReal = vDSP_create_fftsetup(log2n, FFT_RADIX2);  
}

FFTを実行します。FrequencyArrayは、512個のfloat値を保持する単なるデータ構造です。

- (FrequencyArry)performFastFourierTransformForSampleData:(SInt16*)sampleData andSampleRate:(UInt16)sampleRate   
{  
    NSLog(@"log2n %i n %i,  nOver2 %i", log2n, n, nOver2);

    // n = 1024
    // log2n 10
    // nOver2 = 512

    for (int i = 0; i < n; i++) {
        originalReal[i] = (float) sampleData[i];
    }

    vDSP_ctoz((COMPLEX *) originalReal, 2, &A, 1, nOver2);

    vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_FORWARD);

    float scale = (float) 1.0 / (2 * n);

    vDSP_vsmul(A.realp, 1, &scale, A.realp, 1, nOver2);
    vDSP_vsmul(A.imagp, 1, &scale, A.imagp, 1, nOver2);

    vDSP_ztoc(&A, 1, (COMPLEX *) obtainedReal, 2, nOver2);

    FrequencyArry frequencyArray;

    for (int i = 0; i < nOver2; i++) {
        frequencyArray.frequency[i] = log10f(obtainedReal[i]); // Magnitude in db???
    }

    return frequencyArray;  
}

音楽に合わせて動くように見えますが、出力はいつもちょっと変に見えます。

このようないくつかの非常に良い投稿のおかげで、これまでに来たことをうれしく思います: アップルのFFTを使用してフレームワークを加速する

でも今はどうしたらいいのかわからない。私は何が欠けていますか?

4

1 に答える 1

16

まず、FFTの前にウィンドウ関数を適用していません。これにより、スペクトル漏れが原因でスペクトルが不鮮明になります。

次に、FFT出力ビンの実数成分を使用してdBの大きさを計算しているだけです。複素数の大きさを使用する必要があります。

magnitude_dB = 10 * log10(re * re + im * im);
于 2012-05-17T13:29:04.007 に答える