Using jit.fft with Audio P1: Making a buffir~ Graphically


    Jan 21 2008 | 3:02 am
    I feel like I get a lot from this message board but do not give nearly enough back. Hopefully I can change that. This is the first in a series of patches (2 or 3) showing how jit.fft can be used for offline fft calculations. I do not see much on here about using jit.fft with audio. Hopefully it will be useful to some :)
    In making an arbitrary filter, one of the easiest ways is to put a frequency response into a buffer~ and apply it using index~ and some multiplication inside a pfft~. This patch shows how to get similar results using a different approach. Instead of doing an fft on the incoming audio, it uses the often overlooked buffir~ filter. Normally calculating the coefficients needed would be a hassle, which is where jit.fft comes in handy.
    Drawing in the frequency graph writes into a 1D floating point jit.matrix object that is 256 “samples” wide. This matrix follows the shape of the graph, starting with low frequencies and working upwards. Before taking the fft, the frequency response data has to be mirrored and shifted so that a frequency of zero moves to the outer edges and high frequencies move to the middle. Jit.repos using boundmode 4 provides a simple way to mirror a matrix.
    Now the frequency response is ready, but the jit.fft object also needs some phase values to do an inverse fft. In this case the jit.pack object essentially sets all the phase values to 0 for a linear phase filter. To go from frequency data back to the time domain, jit.fft performs an inverse fft on the data.
    At this point jit.fft outputs all the coefficients we need, but not in the proper order. Previously the data was shifted so that “0” moved to the outer edges of the matrix. Now, the reverse is needed. To arrange the coefficients properly, a jit.repos object (boundmode 2) wraps the data into position. Because the filter is linear phase, it is symmetric and delayed. In this case the “0” point of the data is now in the middle. Because the original frequency response going into jit.fft was on a scale from 0 to 1 and not 0 to 1/(length of the data), it has to be scaled down by a jit.op. Lastly, since the buffir~ object has a length limit of 256 samples, a jit.submatrix grabs the 256 values around the center.

    • Jan 21 2008 | 8:06 am
      Very nice!
      You might want to [clip] the mouse input, to prevent negative amplitudes.
      So many directions to continue... put the spectrum into a feedback system of matrix ops... or run a few of these from a jit.p.shiva... or make a 2D matrix and you get a phase vocoder and plug in jit.bfg or something...
      On Jan 20, 2008, at 7:02 PM, Aaron Faulstich wrote:
      > > I feel like I get a lot from this message board but do not give > nearly enough back. Hopefully I can change that. This is the first > in a series of patches (2 or 3) showing how jit.fft can be used for > offline fft calculations. I do not see much on here about using > jit.fft with audio. Hopefully it will be useful to some :) > > In making an arbitrary filter, one of the easiest ways is to put a > frequency response into a buffer~ and apply it using index~ and > some multiplication inside a pfft~. This patch shows how to get > similar results using a different approach. Instead of doing an fft > on the incoming audio, it uses the often overlooked buffir~ filter. > Normally calculating the coefficients needed would be a hassle, > which is where jit.fft comes in handy. > > Drawing in the frequency graph writes into a 1D floating point > jit.matrix object that is 256 “samples” wide. This > matrix follows the shape of the graph, starting with low > frequencies and working upwards. Before taking the fft, the > frequency response data has to be mirrored and shifted so that a > frequency of zero moves to the outer edges and high frequencies > move to the middle. Jit.repos using boundmode 4 provides a simple > way to mirror a matrix. > > Now the frequency response is ready, but the jit.fft object also > needs some phase values to do an inverse fft. In this case the > jit.pack object essentially sets all the phase values to 0 for a > linear phase filter. To go from frequency data back to the time > domain, jit.fft performs an inverse fft on the data. > > At this point jit.fft outputs all the coefficients we need, but not > in the proper order. Previously the data was shifted so that > “0” moved to the outer edges of the matrix. Now, the > reverse is needed. To arrange the coefficients properly, a > jit.repos object (boundmode 2) wraps the data into position. > Because the filter is linear phase, it is symmetric and delayed. In > this case the “0” point of the data is now in the middle. > Because the original frequency response going into jit.fft was on a > scale from 0 to 1 and not 0 to 1/(length of the data), it has to be > scaled down by a jit.op. Lastly, since the buffir~ object has a > length limit of 256 samples, a jit.submatrix grabs the 256 values > around the center. >
    • Oct 01 2013 | 2:07 pm
      Hello SKRASMS! I'don't know if you will read this post but i have to try. Your patch is great! it works very well.
      What if i want the coefficients an amplitude flat response and an arbitrary phase response? I've tried to put all ones on the left inlet of the jit.pack and the desired response in the second but all i've got is a phase running from 0rad to -400rad!
      Any suggestion?