Goz*_*Goz 11
它相当容易.您需要执行FFT,然后总结您感兴趣的箱.您选择的大部分内容取决于音频的采样率.
然后,您需要选择适当的FFT顺序,以便在返回的频率仓中获得良好的信息.
因此,如果您执行8阶FFT,则需要256个样本.这将返回128个复杂的对.
接下来,您需要将这些转换为幅度.这其实很简单.如果你正在使用std :: complex,你可以简单地在复数上执行std :: abs,你将得到它的大小(sqrt(r ^ 2 + i ^ 2)).
有趣的是,在这一点上有一种叫做Parseval定理的东西.该定理表明,在执行傅立叶变换之后,返回的二进制位的总和等于输入信号的均方和.
这意味着要获得一组特定区间的振幅,您可以简单地将它们加在一起除以它们的数量,然后再用sqrt得到这些区间的RMS振幅值.
那么这会让你离开?
那么你需要弄清楚你要加在一起的垃圾箱.
现在假设你的采样率是8kHz.该尼奎斯特速率说你可以在8kHz的采样代表最高频率为4kHz.因此每个箱代表4000/128或31.25Hz.
因此,如果前10个音箱(高达312.5Hz)用于低音频率.Bin 10到Bin 63代表中频.最后bin 64到127是三重奏.
然后,您可以如上所述计算RMS值,并获得RMS值.
可以通过执行将RMS值转换为dBFS值20.0f * log10f( rmsVal );.这将返回从0dB(最大幅度)到-infinity dB(最小幅度)的值.请注意,振幅范围不应为-1到1.
为了帮助您,这里有一些基于C++的iPhone类(它使用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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1314 次 |
| 最近记录: |