# Phase Vocoder

A spectral algorithm for independent time and pitch manipulation.

Uses discrete Fourier transform (DFT / FFT).

# 1 Time Stretch

# 1.1 Parameters

These can be tuned to taste.

MM: input audio block size (integer, eg 8192).

ΔI\Delta I: input audio hop size (integer, eg 19).

NN: zero-padded block size (for DFT, integer, eg 262144).

ΔO\Delta O: output audio hop size (integer, eg 432).

The time dilation factor is ΔOΔI\frac{\Delta O}{\Delta I}.

# 1.2 Algorithm

Take MM samples of input audio every ΔI\Delta I samples.

Multiply by raised cosine window of length MM (peak amplitude 22, mean 11).

Zero-pad to length NN, call it x(n)x(n) where nn is the block index in 0,1,2,0, 1, 2, \ldots.

Take the discrete Fourier transform of x(n)x(n), call it X(n)X(n).

For each bin, normalize the (complex-valued) ratio X(n)X(n1)\frac{X(n)}{X(n - 1)} to magnitude 11, and raise it to the power ΔOΔI\frac{\Delta O}{\Delta I} (which need not be an integer). Call the result δθ(n)\delta \theta(n). In case of division by zero or other badness, set δθ(n)=1\delta \theta(n) = 1.

Increment the phase of each bin by θ(n)=θ(n1)×δθ(n)\theta(n) = \theta(n - 1) \times \delta \theta(n) and normalize (just to be safe in case of rounding errors). Phase of θ(1)\theta(-1) is probably arbitrary but should have magnitude 11.

Then the output Fourier transform has the input’s magnitude with the accumulated phase: Y(n)=|X(n)|×θ(n)Y(n) = |X(n)| \times \theta(n).

Take the inverse Fourier transform of Y(n)Y(n), call it y(n)y(n).

Multiply by raised cosine window of length MM (peak amplitude 22, mean 11).

Multiply by gain factor: G=ΔOM×NG = \frac{\Delta O}{M \times N}. This assumes that the gain of the DFT/FFT is not normalized.

Accumulate MM samples spaced every ΔO\Delta O samples to output audio stream (overlap-add).

# 1.3 References

  • Pure-data documentation 3.audio.examples/I07.phase.vocoder.pd (Pd version 0.53).