0

I would like to use the EZAudio framework to do realtime microphone signal FFT processing, along with some other processing in order to determine the peak frequency.

The problem is, the EZmicrophone class only appears to work on 512 samples, however, my signal requires an FFT of 8192 or even 16384 samples. There doesnt appear to be a way to change the buffer size in EZMicrophone, but I've read posts that recommend creating an array of my target size and appending the microphone buffer to it, then when it's full, do the FFT.

When I do this though, I get large chunks of memory with no data, or discontinuities between the segments of copied memory. I think it may have something to do with the timing or order in which the microphone delegate is being called or memory being overwritten in different threads...I'm grasping at straws here. Am I correct in assuming that this code is being executed everytime the microphone buffer is full of a new 512 samples?

Can anyone suggest what I may be doing wrong? I've been stuck on this for a long time.

Here is the post I've been using as a reference: EZAudio: How do you separate the buffersize from the FFT window size(desire higher frequency bin resolution).

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

    });

}
Community
  • 1
  • 1
geir58
  • 21
  • 2

1 Answers1

0

You likely have threading issues because you are trying to do work in some blocks that takes much much longer than the time between audio callbacks. Your code is being called repeatedly before prior calls can say that they are done (with the FFT setup or clearing the FFT buffer).

Try doing the FFT setup outside the callback before starting the recording, only copy to a circular buffer or FIFO inside the callback, and do the FFT in code async to the callback (not locked in the same block as the circular buffer copy).

hotpaw2
  • 70,107
  • 14
  • 90
  • 153