Build with this node

Start with a prompt in Studio, or copy it into your own coding agent.

Ask Studio

@maruaudio/dsp/spectral/pitch-shifter shifts the pitch of a monophonic signal by time-domain pitch-synchronous overlap-add (TD-PSOLA). The input period is a control input, set from a source frequency: pitch detection and voicing policy belong to another DSP node. Analysis marks are placed one period apart, each refined by correlation (normalized by the candidate's energy) within a quarter period of the expected position. Raised-cosine grains two periods wide are taken at the mark nearest each synthesis point and overlap-added every period / ratio samples; the output is the accumulated sum divided by the accumulated window weight.

Parameters

PathSetterRange as codedDefaultUnit
semitonessetPitchShifterSemitones−12 to +12, giving a ratio of 0.5 to 2ratio 1semitones
frequencyHzsetPitchShifterSourceFrequencyClamped to sampleRate / 640.. sampleRate / 40; the period is then 40 to 640 samples220Hz

Lifecycle

initPitchShifterNode(sampleRate) preallocates two 4096-sample rings, a window sum ring and 64 marks, with the rate bounded to 8 to 192 kHz. Then setters → pitchShifterNodeTick(state, x) per sample → resetPitchShifterNode, which clears the rings and marks and keeps ratio and period. preparePitchShifterNodeSampleRate re-stamps the bounded rate and re-derives the period from the stored source frequency, keeping history. @maru/analysis-pitch-detector can drive the period through updatePitchShifterFromDetector.

When to use it

Transposing a monophonic voice or instrument by up to an octave either way when its pitch is known, from a detector or from the note being played.

Limits

  • Mono sample tick with a fixed latency of 1280 samples (PITCH_SHIFTER_LATENCY_SAMPLES); output is 0 until then.
  • At most two analyses and four grains per tick, with a 321-lag search and a 640-sample correlation bound, so every loop is bounded.
  • The rings are fixed in samples, so the supported source pitch scales with the rate: 75 to 1200 Hz at 48 kHz.
  • Where the window weight is below 10⁻⁶ the output is 0. The leaf playground demo notes that low-level or aperiodic input may not track reliably.

Algorithm properties and proofs

No Lean 4 proof is mapped to this node.

Explore proofs alongside performance

Parameters

ParameterTypeSetter
Frequency hz frequencyHzfloatsetPitchShifterSourceFrequency
Semitones semitonesfloatsetPitchShifterSemitones

Ports

  • In ininput · audio · mono
  • Out outoutput · audio · mono

One sample per pitchShifterNodeTick call.

Dependencies

None: this node imports no other node.

Dependents

Used by

No plugin with a published composition uses this node yet.