Frequency resolution inside a fft bin
Hello world,
here is another question. I am using a patch that finds the central frequency of the bin with maximum amplitude. The frequency resolution is 10.77 Hz and I use the maximum FFT size, 4096. The sampling rate is 44.1 kHz and I want to keep that as it is.
So, is it possible to increase the frequency resolution locally inside that bin? My point is to find the exact (or close to that) frequency with maximum amplitude. In general I am working with EEG data, which means quite low frequencies. What I am trying to do is to calculate the maximum amplitude frequency and scale it to another more audible range. I am aware of objects like sigmund, but it also lacks of stability at low frequencies.
Thx
Linear bins is how the Fourier transform works. If you want something other than a linear subdivision of the sampling rate, you're going to have to go for something other than a Fourier transform (in general) and the FFT (specifically).
Since you say you're working with low-frequency data coming from an EEG, it's not clear why you need as high a sampling rate as 44.1 kHz. But if you have some other compelling reasons to keep the SR, then «shrug» there's nothing to be done there.
You might try looking at the phase component of your FFT to try to fine-tune the frequency. I don't know if (or how well) that actually works, but there is some information in there. You might need to do some research with some heavy-duty math.
Otherwise, you might want to look at completely different approaches to frequency recognition. DTMF-decoding, for instance, can be done with simple band-pass filters. BPFs probably have limitations in the frequency range you seem to be working in, but they might be worth looking at.
Sorry not to have a simple recipe for you here.
Hey,
Thx for the answer. Well as far as I know low frequencies are much more difficult to be detected. So If I scale the EEG signal into another higher frequency range, the resolution would be better.
Do you know how this scaling procedure should be done? What should I keep in mind?
What about low pass filtering the signal, so you only have frequencies below, say, 100 Hz. (sounds reasonable for EEG data to me, but I have no experience with it). After that, amplitude modulate(look at single sideband modulation) the data to shift it in frequency near nyquist to get a high resolution. Say, with a 20000Hz sine wave. After that, FFT.(You can have higher bin number than 4096 with pfft~, by the way). Then just subtrackt 20k from your results.
Should work, right?
cheers!
Thanks.Well, I used freqshift~ to shift my signal around 20kHz as you suggested (like a SSB modulation). However I can't understand clearly how that is increasing the resolution. Can you help me please?
edit:Actually I just tested it and still the frequency resolution is around 10.7. The only difference is that now the signal is around 20kHz.
Hi!
Sorry I wrote that with the morning coffee(not always a good idea). This way, you would increase the frequency resolution per octave, which does not matter to you obviously..
ANyway, why don't you try bigger fft bin size using pfft~?
BTW: fzero~ is not bad with low frequencies. Set the size attribute as large as you can.
Hey thx for the help. Well i suppose MZED you mean the buffer size of fzero~, right? It's seems to be a bit slow at 4096 samples, although it works smoothly.
So anymore suggestions of pitch estimation using EEG data? I am aware of fiddle but it doesn't work with Max 6.
may I allow myself to quote myslef:
ANyway, why don’t you try bigger fft bin size using pfft~?
it was the frame size I eant of course. pfft allows bigger frame sizes than fft~.
You could easily also do an autocorellation if the fundamental frequency is what you're after.
I am working on the pfft solution since you suggested. The thing is that in am not interested in an ifft conversion. Is there a way to output frequency - domain data from pfft?
Can you explain a bit more the auto-correlation idea?
hi, below is a patcher that might help you(hope I got everything right in there..). You can use 'nofft' as a window function argument to fftin/fftout and connect to the real inlet/outlet to transmit signals without the transform. Autocorrelation is a nice way to find when a signal repeats itself. Look for peaks in the correlogram and you got a good chance for obtaining the fundamental freq. cheers!
Hey, many many thanks. Can you elaborate a bit more the peak searching idea? As I get it, you suggest to use a peakamp~ at the outlet 2 of the pfft, right? But how much should be the output interval?
Moreover, why that gives us the fundamental freq?
Hi, not quite.
If you have a spectrum, or a correlogram, it's an array of magnitude values right? If you find the index with the largest value, you got the loudest frequency/the time at which the waveform is most similar to itself(in case of autocorrelation).
I recently did the whole peak finding in an array in python(using thomas grill's [py]/[pyetx]).. not sure how to find the maximum index of one or multiple signal vectors using MSP. I guess gen~ is perfect for that, though! Anyway, Before going any deeper this path, I'd do some more searching on the forums/for externals. What about zsa.descriptors? There is a lot of stuff that should be really useful here.
cheers!