I think you want to spend some time with MSP tutorial #26. Also look at #25.
Quickly, the frequencies of individual fft bins don't change. Each bin represents a bandwidth of (Sample Rate)/(total number of samples). So, a 1024 sample fft has 512 frequency bins of ~43 HZ each -- at 44.1k samples per second. fft~ and pfft~ output a stream of bin numbers.
For amplitude: if you run the real and imaginary outputs of fft~ or pfft~ into cartopol~, the left outlet of cartopol~ is the amplitude for that specific bin.
I'm also having issues with this... mzed, you're example patch didn't seem to work for me!
I'm trying to use the amplitude values that are output to obtain the frequency with the highest amplitude value - to then use generate a saw wave with that frequency... any ideas on how I would go about this?
I know its been a long time since the last post but I hope I will get an answer. So i am using exactly the same patch that MZED posted (without gen), however I have a signal with sampling rate 256Hz. Do you have any idea what changes should I do so as to work properly? I suppose my question is mostly for MZED but any help is welcomed.
Let me make that more clear. The sampling rate in the audio setup menu is of course set at 44100kHz. However I want to do the same task with your patch but with an EEG data signal which has sampl. rate = 256Hz.
"My" patch is completely same to yours but instead of having that sound generator I have a .wav sample with s.r. = 256Hz played. The problem is that I get mostly zero-frequency as exit, no matter how much I decrease the bin's range.
At the end of each fft (edge~) it uses Uzi to scan the buffered results. For each result, the bin index is stored in the first "i" object. If the amplitude in that bin is the highest so far (tested by peak~), the bin index is banged into the second int object. When Uzi is done, it bangs the final result out of that same int object.
Hey, here is my patch. I load .wav file dok1 (it is attached) to the buffer and then its the same process. The only changes are:
1. Instead of dpstate, I use the fixed number 256 (you should enter it in the number box before the patch starts)
2. I used cycle instead of saw
3. I multiply the outcome with 250 just to have a more audible frequency
The problem is that most of the time the exit is zero frequency. Moreover the frequency resolution should be around 0.063 Hz (sampling rate/fft size) but it doesn't seem like changes of that scale are perceptible.
play~ is going to be playing back samples from the buffer at whatever the sample rate is set to in Max. So, if your samples were recorded at 256k, then pitch is going to be very high. I think you'd want to divide multiply the estimated pitch (right before the saw~) by ((.wav file sample rate)/(current max sample rate)).
I'm still kind of confused by what you're doing though, so I could be giving you the wrong answer.
Well, what I am trying to do in a few words is a frequency scaling. I have an EEG data signal which is a .wav file at 256Hz (sampling rate). With your patch I am trying to find the frequency with the highest amplitude value and then scale it to an audible range of 250Hz - 22kHz. Your patch works perfectly for a sample with S.R. = 44100Hz, but not so good for S.R. = 256Hz. What can I do?
Hey MZED, I know it's been a long time but I hope I'll get an answer.
I am using your patch that finds the central frequency of a bin with maximum amplitude. I mostly interested in lower frequencies such as 4-30Hz. However is not possible to have a resolution lower than 10.77Hz as long as the range of every bin is 10.77 (samp.rate = 44100/fft_size = 4096). As far as I know Max doesn't support fft size bigger than 4096. So, what can I do to have a better frequency resolution?
Hey Seabed, I had a similar problem trying to perform FFT on a low sampling rate signal. I have a guess as to what the problem is. From what I understand, sig~ will turn any number into a signal at the DSP sampling rate (usu. 44100Hz). Whenever a new value comes in, it jumps to the new value (or maybe it's interpolated, but it doesn't matter for this point). So every 1/256 seconds, you're getting a new value, but that's really slow compared to the DSP sampling rate of 44100Hz. The result is that at most FFT window lengths (say, 512), you're only getting 512*(1/44100) = 0.01s of signal for each of your FFT windows, whereas you're only getting a new sample every 1/256 = 0.004s. That is each window only contains roughly two 256Hz-sampled-points (I suppose you could max out the FFT window length to 4096 and get some more points, but it's probably still not going to be good enough). That's my best guess anyway -- let me know if you think it's not right.
Anyway, I was able to get an FFT of arbitrary-sample rate signals using jit.fft. Take a look at my patcher and let me know if you have any ideas or questions.
TLDR, fft~ only operates on DSP sample rate signals, which isn't helpful if you're looking for lower frequencies. Use jit.matrix and jit.fft to do it.
Hey Poncie, it's nice that you also working on that stuff. Well I am kind of busy this period but I promise you that next week you will have a more informative reply from me.
So far I "solved" the problem by using pfft~ that allows you to have an FFT bigger than 4096.By this way you can increase the frequency resolution. I will check jit. objects and I will upload my patch as soon as possible. Keep in touch
Might be a bit clumsy but I made this frequency splitter for pfft - it outputs 11 different bands (I have another somewhere that does 31 bands) and you could easily work out which had the highest amplitude out of pfft - I guess you could have more frequency bands too :
this is nice if you want to split your signal in bands, but in order to have a better frequency resolution you have to increase the FFT size. Here it is how i did it:
I am still interested in Poncie's patch but I haven't understand exactly how it works. By the way, it might be a good solution to interpolate a signal which is sampled to a lower frequency than 44100Hz. At least this is what I did with the EEG signals.
I'm trying to do this with pfft~ and having trouble. Number~ won't pull signal data from fftin~ bin index output. Its just all 0's. Has anyone stored amplitude data by bin index in an array from pfft~ not just fft~?