@maruaudio/dsp/spectral/voice-shifter is a monophonic TD-PSOLA shifter built for pitch correction. Analysis marks are placed pitch-synchronously, tracked by correlation at sub-sample positions and anchored on the low-passed waveform peak, so output pitch follows the measured mark spacing times the ratio, including the input's own jitter and vibrato. The ratio sets only the spacing of the next synthesis mark and is smoothed per sample. Each grain is resampled by an independent formant factor while its spacing follows the ratio. A fixed latency and a latency-aligned dry path let the output crossfade to dry input while the caller reports unvoiced audio.
Parameters
| Path | Setter | Range as coded | Default | Unit |
|---|---|---|---|---|
ratio | setVoiceShifterRatio | 0.4454 to 2.2449 (±14 semitones); 2 ms smoothing, immediate before the first sample | 1 | ratio |
voiceShifterSemitones | setVoiceShifterSemitones | −14 to +14 | 0 | semitones |
voiceShifterFormantSemitones | setVoiceShifterFormantSemitones | −12 to +12; 0 keeps the formants | 0 | semitones |
periodSamples | setVoiceShifterPeriod | 32 to the instance's maximum period; steers the mark search only | rate / 220 | samples |
voiced | setVoiceShifterVoiced | 0 or non-zero; queued when a voicing delay is set | 0 | flag |
samples | setVoiceShifterVoicingDelay | 0 to the latency, rounded | 0 | samples |
mode | setVoiceShifterUnvoicedMode | 0 dry crossfade, 1 hold the shifted signal once voiced | 0 | index |
Lifecycle
initVoiceShifter(sampleRate, minimumHz) (rate 8 to 384 kHz, floor 40 to 1000 Hz) allocates power-of-two rings sized for the maximum period (ceil(rate / minimumHz), 64 to 1280), the marks, the grain taper and the voicing queue. Then setters, or updateVoiceShifterFromDetector(state, voiced, period) per detector result → voiceShifterTick(state, x) per sample → resetVoiceShifter, which restores runtime state and keeps the controls.
When to use it
Autotune and harmonizer voices, where a detected pitch and a target note give a ratio and the formants should stay with the singer. The Autotune and Harmonizer modules use it.
Limits
- Mono sample tick. Latency is
voiceShifterLatencySamples, 2.5 maximum periods (1719 samples at 48 kHz for the 70 Hz floor), fixed for the instance. - The ratio and formant at a tick shape the grain
lookaheadinput samples earlier (1.5 maximum periods plus four). - Formant factors above one read faster than real time with no anti-alias filter; the source notes folding above
sampleRate / 4at +12 semitones and a lower level for shorter grains. Octave-down shifts keep TD-PSOLA's grain gaps. - The tick allocates nothing, calls no transcendental and loops to compile-time bounds.