Pfft~ Pitch Shift inside Gen~


    Apr 02 2015 | 3:38 am
    Hey there Jean,
    I'm building a pitch shifter which performs in gen~ via pfft~ to optimize performance.
    I wanted to tag you in the forum post given your experience in the field of spectral analysis. I have gained quite a bit of knowledge from your previous works and posts concerning FFT.
    Currently, I believe to have properly determined bin frequency centre and then real frequency, however I have hit a roadblock in respect to outputting the shifted bin index and converting the shifted real frequency back to phase for fftout~.
    I have attached a few images of the patch, specifically inside the pfft~ and the embedded gen~ code. Currently shifting ratio comes though pfft~ input 2 (@comment ShiftRatio)
    If anyone could chime in with some insight I would really appreciate it. I have the feeling I'm close to success but over looking something simple!

    • Jean-Francois Charles's icon
      Jean-Francois Charles
      Apr 07 2015 | 6:07 am
      Hi, thanks for the question. It is not clear to me which algorithm you want to implement. Inside your gen~ object, I see that you do not change the amplitude. Yet, you have to "move" the energy from bins to other bins to achieve pitch shifting. See here a basic frequency shifter - not a pitch shifter. Just to illustrate that what is "frequency" in the time domain becomes time (see [delay~]) in frequency domain... (also works this way because of the way pfft~ outputs sequentially the data related to successive bins).
    • flec8's icon
      flec8's icon
      Apr 07 2015 | 4:07 pm
      Hey there Jean,
      I'm glad to see your response and value the support.
      Our plan is to implement this basic structure:
      Shift Ratio = Shift to Freq / Root Freq
      Then in pfft~:
      Bin Freq = Bin Index * (Sample Rate / FFT size)
      followed by,
      Freq = Bin Freq + (phase difference * (sample rate / (2π * FFT window size) ) )
      Freq x Shift Ratio = Shifted Freq
      Shifted Freq - Bin Freq = New phase offset
      Bin Index x Shift Ratio = Shifted Bin Index
      Then we have to repack them out of pfft~ for the inverse transform. This seems to be where we're having issues.
      If I'm understanding your explanation correctly, it would appear that we've currently implemented a frequency shifter and that the Amp must be shifted in accordance with its respective Bin Index to shift the pitch.
      Let me know what you think as your insight is greatly appreciated! Thank you.
    • flec8's icon
      flec8's icon
      Apr 09 2015 | 1:22 am
      What are your general thoughts on implementing pitch shifting inside of gen~? Would you recommend Jitter over it?
    • Jean-Francois Charles's icon
      Jean-Francois Charles's icon
      Jean-Francois Charles
      Apr 09 2015 | 7:32 am
      You want to convert one set of spectral data (for instance 1024 points, 512 for amplitude, 512 for phase delta) to another pitch-shifted set of 1024 numbers. It doesn't really matter in this case to store the incoming data in a Jitter matrix, or for instance in a good old buffer: it's just a place in memory. The benefit of using a matrix comes when you want to access and manipulate 2D, 3D, n-D data. Here, you really want to manipulate a table with 2 columns, amplitude and phase delta. This could be the 2 channels of a "stereo buffer". And if you want to go the gen road, you will easily access the buffer from the gen world. I guess you are familiar with the gizmo object: if you just needed a spectral transposition tool for musical goals, you would just use this. In gizmo, I think the spectrum peaks are detected and shifted, whereas more "noisy" parts of the spectrum are ignored or deleted.
    • iamnotnicola's icon
      iamnotnicola's icon
      Apr 12 2020 | 9:16 pm
      any update on this one? I am getting very bad latency with pitchshift~ :(