Getting frequency and amplitude values using FFT~

    Feb 11 2013 | 7:36 pm
    Is there away for getting frequency and amplitude values out of fft~? if so would it be possible for some direction?

    • Feb 11 2013 | 9:03 pm
      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.
    • Feb 11 2013 | 11:51 pm
      Maybe this is somewhat helpful:
    • Feb 16 2013 | 3:26 pm
      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?
    • Feb 16 2013 | 9:39 pm
      This is rather messy, but seems to work. Using gen~.
    • Feb 16 2013 | 10:00 pm
      And without gen~...
      One cheap-o pitch tracker!
    • Mar 01 2013 | 3:32 pm
      Thanks very much!! Now just got to figure out how that works! :)
    • May 30 2014 | 10:47 pm
      Hey all,
      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.
    • May 30 2014 | 11:23 pm
      256 Hz is a crazy-low sampling rate. If you're running at a sample rate that Max supports, then my patch should be fine. The sample rate is reported by the dspstate~ object on the right.
    • May 30 2014 | 11:50 pm
      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.
    • May 30 2014 | 11:59 pm
      This particular patch is doing realtime fft~ with Max and only makes sense in that context. I'm not sure how you're getting samples from your device into Max.
      In general, the frequency for each bin is approximately: (bin number) * ((sample rate)/(number of bins))
    • May 31 2014 | 12:11 am
      "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.
    • Jun 02 2014 | 10:20 pm
      Ηey MZED can you please explain to me how subpatch "find_bin" works? I think that any changes I have to do, should be in there. Thanks
    • Jun 02 2014 | 10:27 pm
      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.
      If you post your patch, I could help some more.
    • Jun 04 2014 | 8:49 am
      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.
      Edit:Actually for a safety reason I cant upload the wav file so here it is a link for it
    • Jun 12 2014 | 8:29 pm
      So? Any new thoughts? I am really stuck at this part.
    • Jun 12 2014 | 9:52 pm
      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.
    • Jun 13 2014 | 3:12 pm
      Hey, first of all thanks for all this help.
      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?
    • Jun 20 2014 | 11:24 am
      Hi again,
      I have also noticed that defining the length of buffer "spectrum" at samples (buffer spectrum @samps 2048) is not compatible with every Max version. Can I do it in another way?
    • Jul 29 2014 | 6:33 pm
      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?
    • Aug 07 2014 | 2:52 pm
      Once again about this lovely patch.
      I noticed that it's not stable for frequencies higher than 5kHz. You can try an oscillator at 10kHz, the maximum output frequency is stuck at 5502 Hz. Any idea why is this happening?
      EDIT: It seems like the uzi object needs to be same size with the fft size.
    • Aug 07 2014 | 4:30 pm
      Good catch, thanks. Actually, it needs to be the same as the buffer size, which is (fft size / 2). The second half of the fft~ output is a mirror of the first half.
    • Sep 10 2014 | 10:48 pm
      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.
    • Sep 12 2014 | 3:28 pm
      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
    • Sep 21 2014 | 1:30 pm
      Hey Poncie, can you explain to me a bit how your patch works?
    • Sep 22 2014 | 12:42 am
      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 :
    • Sep 29 2014 | 9:39 am
      Hey Augustine,
      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.
    • Sep 21 2016 | 5:19 pm
      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~?
    • Sep 21 2016 | 7:28 pm
      The last example uses pfft~. Just go directly from the fftin~ bin index into poke~, with nothing in between.
    • Sep 21 2016 | 7:29 pm
      Yes, you are looking for phase vocoder patches. One example is in the Max Examples -> MSP -> FFT Fun -> phase-vocoder-sampler