時間の増分(たとえば0.1秒)と0.0から1.0の範囲で、曲から高音と低音のデータを取得する方法を探しています。私はグーグルで検索しましたが、探しているものにリモートで近いものを見つけることができませんでした。最終的には、曲の再生中に高音と低音のレベルを表現できるようにしたいと思います。
ありがとう!
そのかなり簡単です。FFTを実行してから、関心のあるビンを合計する必要があります。選択する方法の多くは、オーディオのサンプリングレートによって異なります。
次に、返される周波数ビンで適切な情報を取得するために、適切なFFT順序を選択する必要があります。
したがって、8 FFTを注文する場合は、256個のサンプルが必要になります。これにより、128の複雑なペアが返されます。
次に、これらを大きさに変換する必要があります。これは実際には非常に簡単です。std :: complexを使用している場合は、複素数に対してstd :: absを実行するだけで、その大きさが得られます(sqrt(r ^ 2 + i ^ 2))。
興味深いことに、この時点でパーセバルの定理と呼ばれるものがあります。この定理は、フーリエ変換を実行した後、返されるビンの合計が入力信号の平均二乗の合計に等しいことを示しています。
これは、ビンの特定のセットの振幅を取得するには、それらを合計してそれらの数で除算し、次にsqrtしてそれらのビンのRMS振幅値を取得できることを意味します。
それで、これはあなたをどこに残しますか?
ここから、どのビンを一緒に追加しているかを把握する必要があります。
ここで、サンプルレートが8kHzであると仮定します。ナイキストレートによると、8kHzのサンプリングで表現できる最高周波数は4kHzです。したがって、各ビンは4000/128または31.25Hzを表します。
したがって、最初の10個のビン(最大312.5Hz)が低音周波数に使用される場合。ビン10からビン63はミッドを表します。最後に、ビン64から127は高音域です。
次に、上記のようにRMS値を計算すると、RMS値が得られます。
RMS値は、を実行することでdBFS値に変換できます20.0f * log10f( rmsVal );
。これにより、0dB(最大振幅)から-無限dB(最小振幅)までの値が返されます。振幅は-1から1の範囲ではないことに注意してください。
これを支援するために、iPhone用のC ++ベースのFFTクラス(内部でvDSPを使用)を少し紹介します。
MacOSFFT::MacOSFFT( unsigned int fftOrder ) :
BaseFFT( fftOrder )
{
mFFTSetup = (void*)vDSP_create_fftsetup( mFFTOrder, 0 );
mImagBuffer.resize( 1 << mFFTOrder );
mRealBufferOut.resize( 1 << mFFTOrder );
mImagBufferOut.resize( 1 << mFFTOrder );
}
MacOSFFT::~MacOSFFT()
{
vDSP_destroy_fftsetup( (FFTSetup)mFFTSetup );
}
bool MacOSFFT::ForwardFFT( std::vector< std::complex< float > >& outVec, const std::vector< float >& inVec )
{
return ForwardFFT( &outVec.front(), &inVec.front(), inVec.size() );
}
bool MacOSFFT::ForwardFFT( std::complex< float >* pOut, const float* pIn, unsigned int num )
{
// Bring in a pre-allocated imaginary buffer that is initialised to 0.
DSPSplitComplex dspscIn;
dspscIn.realp = (float*)pIn;
dspscIn.imagp = &mImagBuffer.front();
DSPSplitComplex dspscOut;
dspscOut.realp = &mRealBufferOut.front();
dspscOut.imagp = &mImagBufferOut.front();
vDSP_fft_zop( (FFTSetup)mFFTSetup, &dspscIn, 1, &dspscOut, 1, mFFTOrder, kFFTDirection_Forward );
vDSP_ztoc( &dspscOut, 1, (DSPComplex*)pOut, 1, num );
return true;
}
高速フーリエ変換のサンプルコードを探しているようです。
答えをカバーすることは非常に大きなトピックです。
必要なツールはすでにiOSで構築されています:vDSP API
これはあなたを助けるはずです:vDSPプログラミングガイド
また、利用可能なFFTサンプルコードもあります
iPhoneFFTもチェックしてみてください。そのコードはわずかに時代遅れですが、「内部」のプロセスを理解するのに役立ちます。
Appleのauriotouch2の例を参照してください。周波数分析から必要なもののUI表現まですべてが含まれています。