重複の可能性:
FFT結果から周波数を取得する方法
aurioTouch2サンプル コードを調査しています。また、描画ビュー関数では、fft データを計算するために常に 1 つの関数が呼び出されるため、さまざまな周波数の電力を計算できます。
Boolean FFTBufferManager::ComputeFFT(int32_t *outFFTData)
{
if (HasNewAudioData())
{
//Generate a split complex vector from the real data
// real1 = -0.005138, real2 = -0.005010; r = -0.005138, im = -0.005010
vDSP_ctoz((COMPLEX *)mAudioBuffer, 2, &mDspSplitComplex, 1, mFFTLength);
//Take the fft and scale appropriately
// FFTSetup mSpectrumAnalysis - koefficients
vDSP_fft_zrip(mSpectrumAnalysis, &mDspSplitComplex, 1, mLog2N, kFFTDirection_Forward);
vDSP_vsmul(mDspSplitComplex.realp, 1, &mFFTNormFactor, mDspSplitComplex.realp, 1, mFFTLength);
vDSP_vsmul(mDspSplitComplex.imagp, 1, &mFFTNormFactor, mDspSplitComplex.imagp, 1, mFFTLength);
//Zero out the nyquist value
mDspSplitComplex.imagp[0] = 0.0;
//Convert the fft data to dB
// calculate complex number abs, write to tmpData
Float32 tmpData[mFFTLength];
vDSP_zvmags(&mDspSplitComplex, 1, tmpData, 1, mFFTLength);
//In order to avoid taking log10 of zero, an adjusting factor is added in to make the minimum value equal -128dB
vDSP_vsadd(tmpData, 1, &mAdjust0DB, tmpData, 1, mFFTLength);
Float32 one = 1;
vDSP_vdbcon(tmpData, 1, &one, tmpData, 1, mFFTLength, 0);
//Convert floating point data to integer (Q7.24)
vDSP_vsmul(tmpData, 1, &m24BitFracScale, tmpData, 1, mFFTLength);
for(UInt32 i=0; i<mFFTLength; ++i)
outFFTData[i] = (SInt32) tmpData[i];
OSAtomicDecrement32Barrier(&mHasAudioData);
OSAtomicIncrement32Barrier(&mNeedsAudioData);
mAudioBufferCurrentIndex = 0;
return true;
}
else if (mNeedsAudioData == 0)
OSAtomicIncrement32Barrier(&mNeedsAudioData);
return false;
}
問題は、画面に表示されるさまざまな周波数を取得する方法です。つまり、私はさまざまなオーディオ周波数に対応する一連のパワーを持っています。また、たとえば、最低周波数の値をどのように理解できますか?
私の視点を示すために更新します。
最低のしきい値 (最低の周波数) は outFFTData[0] であり、最高は outFFTData[last] です。しかし、たとえば、図のどの周波数が outFFTData[0] に関連しているかはわかりません。outFFTData[0] は 16Hz に関連していますか。outFFTData[last] は 22 kHz に関連していますか?
ここで、outFFTData[0] は人間が聞くことができるオーディオの最低周波数に関連していると思います。そして outFFTData[last] は、男性が聞くことができるオーディオの最高周波数に関連しています。
私が間違っている?
更新 2
ここでPaul Rコードを見ました。それは本当にほとんどすべてを示しています。しかし、私が間違っている場合は、訂正してください。
このコードでは:
//Generate a split complex vector from the real data
// real1 = -0.005138, real2 = -0.005010; r = -0.005138, im = -0.005010
vDSP_ctoz((COMPLEX *)mAudioBuffer, 2, &mDspSplitComplex, 1, mFFTLength);
//Take the fft and scale appropriately
// FFTSetup mSpectrumAnalysis - koefficients
vDSP_fft_zrip(mSpectrumAnalysis, &mDspSplitComplex, 1, mLog2N, kFFTDirection_Forward);
vDSP_vsmul(mDspSplitComplex.realp, 1, &mFFTNormFactor, mDspSplitComplex.realp, 1, mFFTLength);
vDSP_vsmul(mDspSplitComplex.imagp, 1, &mFFTNormFactor, mDspSplitComplex.imagp, 1, mFFTLength);
このコード mFFTLength = mAudioBufferLen / 2;
では、周波数の最大値が mDspSplitComplex にindex = mFFTLength - 1
あると思いindex = mFFTLength / 2 - 1
ます。
アップデート 3
私は非常に似たような問題を抱えています。なぜ aurioTouch プロジェクトで最初のバッファのみを使用するのですか。答えは誰でも知っているかもしれません。