2

オーディオビジュアライザーを作成しようとしています。

高速フーリエ変換を使用して周波数を見つけています。

memset(_window, 0, sizeof(float)*_windowSize);
memset(_A.imagp, 0, nOver2 * sizeof(float));

vDSP_hann_window(_window, _windowSize, vDSP_HANN_NORM);

for (int i=0; i < _windowSize; i++) {
    if (player && ioData) {
        _inPutBuffer[i] = ((SInt16*) ioData->mBuffers[0].mData)[i];
    }
}

vDSP_vmul(_inPutBuffer, 1, _window, 1, _transferBuffer, 1, _windowSize);

vDSP_ctoz((COMPLEX*)_transferBuffer, 2, &(_A), 1, nOver2);

vDSP_fft_zrip(_fftSetup, &_A, stride, log2n, FFT_FORWARD);

vDSP_vsmul(_A.realp, 1, &_scale, _A.realp, 1, nOver2);
vDSP_vsmul(_A.imagp, 1, &_scale, _A.imagp, 1, nOver2);

_A.imagp[0] = 0.0f;

vDSP_zvmags(&_A, 1, _obtainedReal, 1, nOver2);

float frequencyArray[n];

for (int i=1; i <=kIndicatorsCount; i++ ) {
    float res = 0;
    for (int j=0; j <=32; j++) {
        res += _obtainedReal[i*32+j];
    }
    res = res / 32;
    OutputBuff[i] = res;
}

ただし、出力は非常に異なる値です。たとえば、出力値が 0 から 1 の場合と 0 から 5.0E +6 の場合があります。

出力値を特定の範囲 (例: 0 から 1) にすることはできますか?

4

2 に答える 2

4

FFT のマグニチュード出力は通常、まさにこの理由からデシベルで視覚化されます。デシベルを使用すると、大きなコンポーネントが存在する場合でも、非常に小さなコンポーネントが表示されます。変換は簡単です。二乗の大きさが得られるのでvDSP_zvmags、次の方法で dB に変換できます。

dbval = 10 * log10(mag2val);

または参照してくださいvDSP_vdbcon

これは、dB 値の最大値で除算することによって 0 から 1 の間で正規化できますが、一定の大きさの視覚化がジャンプする原因となるため、この基準点を動的に変更したくないでしょう。典型的な範囲を把握し、その固定値に正規化する方がよいでしょう。

于 2013-02-15T14:09:17.297 に答える
1

問題はvDSP_zvmags(&_ A、1、_obtainedReal、1、nOver2);であ​​る必要があります。

Appleのドキュメントによると:vDSP_zvmags複素数ベクトルAの大きさの2乗を計算します。

つまり、大きさはピタゴラスの定理によるものであり、vDSP_vpythg(Vector Pythagoras;単精度)を使用する必要があります。

その後、フラグ__vDSP_Fから電力(0)または振幅(1)フラグへのデシベル変換vDSP_vdbconを使用できます。

この助けを願っています

于 2013-02-18T18:42:39.297 に答える