我正在寻找一种方式来获得一首歌曲中的高音和低音数据,以提高时间(例如0.1秒),范围在0.0到1.0之间.我已经google了,但是还没有找到任何东西远离我正在寻找的东西.最终,我想在歌曲播放时能够代表高音和低音级别.
谢谢!
解决方法
它相当容易您需要执行FFT,然后总结您感兴趣的箱子.很多您选择的方式将取决于您的音频采样率.
然后,您需要选择适当的FFT顺序,以便在返回的频率区域中获得良好的信息.
所以如果你做一个订单8 FFT,你将需要256个样本.这将返回128个复数对.
接下来,您需要将它们转换为大小.这其实很简单.如果您使用std :: complex,您可以简单地在复数上执行一个std :: abs,您将拥有其大小(sqrt(r ^ 2 i ^ 2)).
有趣的是,在这一点上有一个叫做Parseval’s theorem的东西.这个定理指出,在执行傅里叶变换后,返回的总和的总和等于输入信号的均方之和.
这意味着为了获得一组特定的仓,您可以简单地将它们加在一起除以它们的数量,然后再乘以sqrt来获得这些仓的RMS振幅值.
那么这样离开你呢?
那么从这里你需要弄清楚你加在一起的哪一个箱子.
>高音定义为2000Hz以上.
>低音在300Hz以下(如果我的记忆正确地服务于我).
>中尺寸在300Hz和2kHz之间.
现在假设你的采样率是8kHz. Nyquist rate表示,您可以在8kHz采样中表示的最高频率为4kHz.因此,每个bin代表4000/128或31.25Hz.
所以如果前10个音箱(高达312.5Hz)用于低音频率.斌10至斌63代表中尉.最后bin 64到127是高音.
然后可以如上所述计算RMS值,并具有RMS值.
通过执行20.0f * log10f(rmsVal),可以将RMS值转换为dBFS值.这将返回从0dB(最大振幅)到-infinity dB(最小振幅)的值.请注意,幅度不在-1到1之间.
为了帮助你,这里有一些我的基于C的FFT类为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,mFFTOrder,kFFTDirection_Forward ); vDSP_ztoc( &dspscOut,(DSPComplex*)pOut,num ); return true; }