在iOS中从音频中提取高音和低音

Mat*_*ich 9 audio waveform extract ios

我正在寻找一种方法来获取歌曲中的高音和低音数据,增加一些时间(例如0.1秒),范围为0.0到1.0.我已经google了一下,但是找不到任何与我正在寻找的东西相近的东西.最终我希望能够在播放歌曲时表现高音和低音水平.

谢谢!

Goz*_*Goz 11

它相当容易.您需要执行FFT,然后总结您感兴趣的箱.您选择的大部分内容取决于音频的采样率.

然后,您需要选择适当的FFT顺序,以便在返回的频率仓中获得良好的信息.

因此,如果您执行8阶FFT,则需要256个样本.这将返回128个复杂的对.

接下来,您需要将这些转换为幅度.这其实很简单.如果你正在使用std :: complex,你可以简单地在复数上执行std :: abs,你将得到它的大小(sqrt(r ^ 2 + i ^ 2)).

有趣的是,在这一点上有一种叫做Parseval定理的东西.该定理表明,在执行傅立叶变换之后,返回的二进制位的总和等于输入信号的均方和.

这意味着要获得一组特定区间的振幅,您可以简单地将它们加在一起除以它们的数量,然后再用sqrt得到这些区间的RMS振幅值.

那么这会让你离开?

那么你需要弄清楚你要加在一起的垃圾箱.

  1. 高音音调定义为2000Hz以上.
  2. 低音音调低于300Hz(如果我的记忆正确地为我服务).
  3. 中频介于300Hz和2kHz之间.

现在假设你的采样率是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)


Rok*_*arc 5

您似乎正在寻找快速傅里叶变换示例代码.

这是一个很大的话题要在答案中涵盖.

您需要的工具已经在iOS中构建:vDSP API

这应该对您有所帮助:vDSP编程指南

而且还有一个FFT示例代码可用

您可能还想查看iPhoneFFT.虽然该代码稍微过时,但它可以帮助您理解"引擎盖下"的过程.