snails.fm/ docs voice tuner

Singing

Control path: once per 64-sample chunk, on the mono sum——— audio   – – – controlx(n)per channelmono sumshift ratios: per chunk, per voiceequal-power pan → stereo busy(n)MCSMono control sumPDPitch detectionpYIN / YINRGTReliability gatesonset · floor · corridorSMFf₀ smoothingTSLTarget selectionScale / MIDIGLDRetune glideMIDISHFLead pitch shifterTD-PSOLA / phase vocoderHarmony voices ×15HVHVHVADT doubles ×4DVDVLatency alignmentALNDry / wet mixMIXz−LDelay-matched dry pathdry (bypass rides this path)

The decision layer hands this page one number per chunk: the shift ratio, target pitch over sung pitch. This page turns that number into your voice at a new pitch, without turning you into a chipmunk and without synthesising anything that wasn't sung.

The physical picture

Voiced sound has a structure worth knowing, because the whole shifter is built on it. Your vocal folds snap shut in a steady rhythm (each closure a tiny click, called a glottal pulse), and pitch is simply how fast those clicks come. Everything else about your sound, the vowels and the character, comes from your vocal tract acting as a filter over the clicks: its resonant peaks are the formants, and they don't move when your pitch does. A high note and a low note through the same throat share the same formants.

So the honest way to change pitch is: change the click rate, leave the filter alone. That is exactly what the default engine does.

The default engine: PSOLA

Pitch-Synchronous Overlap-Add, in four moves:

  1. Find the pulses. An epoch detector locates each glottal closure in the incoming voice. Two detectors ship, switchable via Epochs: ZFF (the default) and Peak.
  2. Cut a grain around each. A small bell-windowed slice of audio, centred on the pulse; one grain per click of the voice.
  3. Re-lay the grains at the new rhythm. Grains are placed back down at spacing divided by the shift ratio: denser spacing is a higher pitch, sparser is lower. The bells overlap and sum smoothly back into a voice.
  4. Keep the formants where they were. Before a grain is laid down, its contents are counter-resampled so the vocal-tract resonances stay at their original frequencies while the pulse rate moves. This is the mechanism that prevents the chipmunk effect: pitch changes, the throat doesn't. The Formant knob exposes this scale directly; its centre means resonances fully preserved. (The general story is on the formants page.)

Consonants and breaths are handled by not handling them. Unvoiced sound has no pulses to re-space, and resynthesising it only degrades it, so it passes through as an exact delayed copy of the input, crossfaded with the synthesised voice at every voiced-unvoiced boundary. Your consonants in the output are your consonants.

Precision here is audible. Grain timing is kept fractional-sample throughout: rounding grain positions to whole samples adds a jitter of up to half a sample at pitch rate, which reads to the ear as a rough, scraping texture. So grain onsets, window shapes, and audio reads are all evaluated at exact fractional positions.

The other engine

A second shifter ships alongside: a phase vocoder, a spectral method that shifts pitch in the frequency domain, with its own formant-preservation scheme. It is not a fallback; it is a different texture. Grain-domain and spectral-domain shifting fail in different, characteristic ways, and different material flatters different engines.

The Engine switch chooses which one renders your voice. At Range = Full, both engines run continuously, latency-aligned, so switching is a seamless, instant A/B. Listen, pick, keep working. At the narrower Ranges only the selected engine runs, and Live mode is PSOLA-only (the reasons are on the time page).

What leaves this page

Your voice, at the decided pitch, formants intact, per channel, on its way to be aligned and mixed. The harmony and doubler voices render through the same machinery, one voice each; their story is the crowd.

last updated · Charlie