gpt4 book ai didi

ios - FFT 输出与 float 缓冲器 AudioUnit

转载 作者:可可西里 更新时间:2023-11-01 05:10:03 26 4
gpt4 key购买 nike

我对 vDSP_zrip 和 AudioUnit 的使用和配置有疑问。事实上我配置 AudioUnit 以将打包数据保存为 float 。我创建了一个循环缓冲区,当这个缓冲区已满时,我计算了一个 fft。我有一个结果,但我不明白为什么 fft 输出不好(参见图)

音频单元配置:

// 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;

循环缓冲区:

_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);
[...]
}
}

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;

其中 _fftsize = _audioSample.capacity()/2

figure

最佳答案

您的输出看起来很合理,所以我会将您的问题更多地解释为“我如何清理这些结果?”

1) 您可能正在使用矩形窗口

这意味着你没有做任何 windowing ,这会在您的结果中引入一些噪音。 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);

然后,每当您要进行 FFT 时,首先对样本进行窗口化(例如,在调用 vDSP_ctoz 之前执行此操作):

 vDSP_vmul(sample.get(), 1, hammingWindow, 1, sample.get(), 1, N);

2) 你可能想对你的结果运行一个幅度函数

这将为您提供类似于您在标准 FFT 条形图音乐可视化工具中看到的结果。在 FFT 之后执行此操作:

vDSP_zvmags(&_complex, 1, &_complex.realp, 1, _fftsize);

之后,_complex.realp 将是一个浮点值数组,表示每个 FFT bin 的大小。

关于ios - FFT 输出与 float 缓冲器 AudioUnit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12642916/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com