0

我想使用 EZAudio 框架进行实时麦克风信号 FFT 处理,以及其他一些处理以确定峰值频率。

问题是,EZmicrophone 类似乎只适用于 512 个样本,但是,我的信号需要 8192 甚至 16384 个样本的 FFT。似乎没有办法更改 EZMicrophone 中的缓冲区大小,但我读过一些帖子,建议创建一个目标大小的数组并将麦克风缓冲区附加到它,然后当它满时,执行 FFT。

但是,当我这样做时,我会得到没有数据的大块内存,或者复制内存段之间的不连续性。我认为这可能与调用麦克风委托的时间或顺序或在不同线程中覆盖内存的时间或顺序有关......我在这里抓住了稻草。我是否正确假设每次麦克风缓冲区充满新的 512 个样本时都在执行此代码?

谁能建议我可能做错了什么?我已经坚持了很长时间。

这是我一直用作参考的帖子: EZAudio:如何将缓冲区大小与 FFT 窗口大小分开(希望更高的频率 bin 分辨率)。

// Global variables which are bad but I'm just trying to make things work
float tempBuf[512];
float fftBuf[8192];
int samplesRemaining = 8192;
int samplestoCopy = 512;
int FFTLEN = 8192;
int fftBufIndex = 0;


#pragma mark - EZMicrophoneDelegate
-(void)    microphone:(EZMicrophone *)microphone
     hasAudioReceived:(float **)buffer
       withBufferSize:(UInt32)bufferSize
 withNumberOfChannels:(UInt32)numberOfChannels {

    // Copy the microphone buffer so it wont be changed
    memcpy(tempBuf, buffer[0], bufferSize);


    dispatch_async(dispatch_get_main_queue(),^{


        // Setup the FFT if it's not already setup
        if( !_isFFTSetup ){
            [self createFFTWithBufferSize:FFTLEN withAudioData:fftBuf];
            _isFFTSetup = YES;
        }

        int samplesRemaining = FFTLEN;


        memcpy(fftBuf+fftBufIndex, tempBuf, samplestoCopy*sizeof(float));
        fftBufIndex += samplestoCopy;
        samplesRemaining -= samplestoCopy;

        if (fftBufIndex == FFTLEN)
        {

            fftBufIndex = 0;
            samplesRemaining = FFTLEN;
            [self updateFFTWithBufferSize:FFTLEN withAudioData:fftBuf];
        }

    });

}
4

1 回答 1

0

您可能遇到线程问题,因为您尝试在某些块中执行比音频回调之间的时间长得多的工作。您的代码在之前的调用可以说它们完成之前被重复调用(使用 FFT 设置或清除 FFT 缓冲区)。

尝试在开始录制之前在回调外部进行 FFT 设置,仅复制到回调内部的循环缓冲区或 FIFO,并在与回调异步的代码中执行 FFT(不与循环缓冲区副本锁定在同一块中)。

于 2015-04-24T16:17:42.697 回答