Using Apple's Accelerate framework, FFT, Hann windowing and Overlapping

巧了我就是萌 提交于 2019-12-20 02:29:05

问题


I'm trying to setup FFT for a project and really didn't get a clear picture on things... Basically, I am using Audio Units to get the data from the device's microphone. I then want to do FFT on that data. This is what I understand so far: I need to setup a circular buffer for my data. On each filled buffer, I apply a Hann window then do an FFT. However, I still need some help on overlapping. To get more precise results, I understand I need to use this expecially since I am using windowing. However, I can't find anything on this... Here's what I have so far (used for pitch detection):

// Setup -------------  
UInt32 log2N          = 10; // 1024 samples  
UInt32 N              = (1 << log2N);  
FFTSetup FFTSettings  = vDSP_create_fftsetup(log2N, kFFTRadix2);  
COMPLEX_SPLIT FFTData;  
FFTData.realp         = (float *) malloc(sizeof(float) * N/2);  
FFTData.imagp         = (float *) malloc(sizeof(float) * N/2);  
float * hannWindow = (float *) malloc(sizeof(float) * N);  

// create an array of floats to represent a hann window  
vDSP_hann_window(hannWindow, N, 0);

// FFT Time ----------  
// Moving data from A to B via hann window  
vDSP_vmul(A, 1, hannWindow, 1, B, 1, N);                                 

// Converting data in B into split complex form  
vDSP_ctoz((COMPLEX *) B, 2, &FFTData, 1, N/2);  

// Doing the FFT  
vDSP_fft_zrip(FFTSettings, &FFTData, 1, log2N, kFFTDirection_Forward);   

// calculating square of magnitude for each value  
vDSP_zvmags(&FFTData, 1, FFTData.realp, 1, N/2);  

// Inverse FFT  
vDSP_fft_zrip(FFTSettings, &FFTData, 1, log2N, kFFTDirection_Inverse);  

// Storing the autocorrelation results in B  
vDSP_ztoc(&FFTData, 1, (COMPLEX *)B, 2, N/2);  

vDSP_Length lastZeroCrosssing;  
vDSP_Length zeroCrossingCount;  
vDSP_nzcros(B, 1, N, &lastZeroCrossing, &zeroCrossingCount, N);  

// Cleanup -----------  
vDSP_destroy_fftsetup(FFTSettings);  
free(FFTOutput.realp);  
free(FFTOutput.imagp);  
free(hannWindow);

So where and how would I include overlapping? Also, any code snippets would be more then welcome. Thanks

UPDATE:

The final goal for this project is to do a fingerprinting of the audio, as close to real-time as possible so I need the results as accurate as possible - thus the overlapping. For this purpose I think I could actually drop all the part from inverse to cleanup.


回答1:


You don't actually need to overlap - typically frames are overlapped to give higher resolution in the time axis, e.g. for plotting spectrograms or for estimating note onset times. You could just get your code working without overlapping for now, as it's less complicated, and then decide whether you need higher resolution on the time axis later.

If you decide you do want to add overlapping then you will need to save a chunk of the previous buffer (e.g. 50%) and then for each new buffer you will process two complete buffers as follows:

  • process last 50% of old buffer + first 50% of new buffer
  • process 100% of new buffer
  • save last 50% of new buffer for next iteration

For different overlap percentages a similar logic applies.

Note that increasing overlap beyond a certain point can become counterproductive as the required processing bandwidth increases greatly with little gain in resolution.



来源:https://stackoverflow.com/questions/18931905/using-apples-accelerate-framework-fft-hann-windowing-and-overlapping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!