pitch_correct.h
Pitch correction: detect, decide, shift.
#include <sonore/pitch_correct.h>- 1type
- Guides: Getting started, MIDI and MPE
On this page
Design notes
"Autotune" is three things glued: YIN finds the pitch, a scale says where it should be, and the voice is moved there. The glue is where it goes wrong -- a corrector that snaps on every frame warbles, one that trusts a low-confidence estimate on a breath jumps an octave, one that decides in hertz instead of cents snaps unevenly. So: decisions are made in cents against a twelve-bit scale mask, only when the detector is confident, and the correcting ratio glides to its target over a retune time -- zero is the robot, a hundred milliseconds is a singer.
The moving is pitch-synchronous overlap-add (PSOLA), the method made for one voice: the input is cut into grains two periods long, centred on its own pitch marks, and laid down again a period divided by the ratio apart. Every harmonic moves by exactly the ratio, at any rate, and the formants stay where the throat put them. It replaced a phase vocoder with a fixed 2048-point frame, whose bins were too wide for a low voice: at 96 kHz a voice at 112 Hz has its harmonics under three bins apart, and the vocoder's phase locking moved them all by the fundamental's offset instead of scaling them -- harmonics 2 to 5 landed 16 to 25 cents sharp of the note it aimed at, a 63 Hz voice at 48 kHz 17 to 23 cents, and at 384 kHz the fundamental was lost.
Latency is two and a half of the longest period the corrector handles -- 42 ms with the default 60 Hz floor, the same at every rate -- and the detector's hop is what the correction lags the pitch by, which is the trade every real-time corrector makes.
The detector hears the input decimated to about 48 kHz, whatever the session runs at. Its window is a fixed 2048 samples and holds a period of at most 1022: 47 Hz at 48 kHz, but 94 at 96 and 188 at 192 -- above the corrector's own 60 Hz floor, so a low voice at a high rate was misread at the longest lag there was and "corrected" to the wrong note.
Included by dsp.h.
Types 1
SIZE: the detector (~70 KB, a member) and the shifter's buffers, about seven of the longest period long, allocated by setSampleRate().