FFT output with AudioUnit float buffer

I have a problem using vDSP_zrip and AudioUnit and customization. I actually configured AudioUnit to save the packed data as a float. I create a circular buffer, and when this buffer is full, I compute fft. I have a result, but I don't understand why fft ouput is bad (cf figure)

AudioUnit Configuration:

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

Loop buffer:

 _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 call:

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

where _fftsize = _audioSample.capacity()/2

figure

+4
source share
1 answer

Your conclusion seems pretty reasonable, so I'm going to interpret your question as something more: "How to clear these results?"

1) You are probably using a rectangular window

This means that you are not doing windowing , which will result in some noise in your results. vDSP comes with some window execution features that you can use as follows:

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

Then, whenever you are going to make your FFT, first open your samples (like, do this before calling vDSP_ctoz):

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

2) You might want to run the amplitude function according to your results.

This will give you results similar to those you will see in the standard FFT line chart visualization visualization tool. Do it after FFT:

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

After that, _complex.realp will be an array of float values โ€‹โ€‹representing the size of each FFT bit.

+9
source

Source: https://habr.com/ru/post/1436844/


All Articles