xun*_*ien 4 core-audio audiounit ios accelerate-framework
我的vDSP_zrip和AudioUnit使用和配置有问题.实际上我配置了AudioUnit来将打包数据保存为float.我创建一个循环缓冲区,当这个缓冲区已满时,我计算一个fft.我有结果,但我不明白为什么fft输出不好(参见图)
AudioUnit配置:
// describe format
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 44100;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagsNativeEndian|kAudioFormatFlagIsPacked|kAudioFormatFlagIsFloat|kAudioFormatFlagIsNonInterleaved;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1; // mono
audioFormat.mBitsPerChannel = sizeof(float) * 8;
audioFormat.mBytesPerFrame = audioFormat.mChannelsPerFrame * sizeof(float);
audioFormat.mBytesPerPacket = audioFormat.mFramesPerPacket * audioFormat.mBytesPerFrame;
Run Code Online (Sandbox Code Playgroud)
循环缓冲区:
_audioSample = new AudioSample(8192, 44100);
// in recording callback :
for(int i = 0; i < bufferList.mNumberBuffers; ++i)
{
if(!status)
{
if(_sample->needData())
_sample->put((float*)bufferList.mBuffers[i].mData,
bufferList.mBuffers[i].mDataByteSize);
[...]
}
}
Run Code Online (Sandbox Code Playgroud)
vDSP电话:
// get a split complex vector (real signal divided into an even-odd config
vDSP_ctoz((COMPLEX *)sample.get(), 2, &_complex, 1, _fftsize);
vDSP_fft_zrip(_fftsetup, &_complex, 1, _log2n, kFFTDirection_Forward);
// scale (from vDSP reference)
float scale = 1.0 / (2.0 * _samples);
vDSP_vsmul(_complex.realp, 1, &scale, _complex.realp, 1, _fftsize);
vDSP_vsmul(_complex.imagp, 1, &scale, _complex.imagp, 1, _fftsize);
_complex.imagp[0] = 0.0;
Run Code Online (Sandbox Code Playgroud)
哪里 _fftsize = _audioSample.capacity()/2

你的输出看起来很合理,所以我将把你的问题解释为"如何清理这些结果?"
1)你可能正在使用矩形窗口
这意味着您没有进行任何窗口操作,这会在结果中引入一些噪音.vDSP附带了一些执行窗口的功能,您可以像这样使用:
// N = number of samples in your buffer
int N = _audioSample.capacity();
// allocate space for a hamming window
float * hammingWindow = (float *) malloc(sizeof(float) * N);
// generate the window values and store them in the hamming window buffer
vDSP_hamm_window(hammingWindow, N, 0);
Run Code Online (Sandbox Code Playgroud)
然后,无论何时您要进行FFT,都要先将样品放样(例如,在vDSP_ctoz调用之前执行此操作):
vDSP_vmul(sample.get(), 1, hammingWindow, 1, sample.get(), 1, N);
Run Code Online (Sandbox Code Playgroud)
2)您可能希望对结果运行幅度函数
这将为您提供类似于您在标准FFT条形图音乐可视化器中看到的结果.在FFT 之后执行此操作:
vDSP_zvmags(&_complex, 1, &_complex.realp, 1, _fftsize);
Run Code Online (Sandbox Code Playgroud)
之后,_complex.realp将是一个浮点值数组,表示每个FFT bin的大小.
| 归档时间: |
|
| 查看次数: |
1670 次 |
| 最近记录: |