Chapter 1
What is pitch, anyway?
Almost every pitched sound in the natural world is a stack of pure tones called partials, all sounding at once. A guitar string is the kind of sound most pitch algorithms were built around: its partials sit at neat whole-number multiples of the lowest one — 1×, 2×, 3×, 4×. Stacks like that are called harmonic, and they add up to a waveform that repeats over and over, like a loop.
The lowest partial is the fundamental — f₀. Think of the partials as singers holding one chord. The others sing at exact multiples of the lowest voice's speed, so they all draw breath at the same instant. That shared breath is the waveform's repeat.
Pitch is not one of the singers. It's the name you'd give what you heard — one note, not seven. Your ear does the blending for free, and for harmonic sounds it always names the lowest voice. Which is why the two words get used as if they were one.
A struck bronze bar — a saron in a Javanese gamelan — follows different physics. Its partials can sit at ratios like 1 : 2.76 : 5.40. Nothing lines up, so the waveform never repeats — and standard assumptions in the math behind a particular algorithm can fall apart. Thusly, some methods will reliably find the pitch of 'smoother' sounding harmonic instruments, while others will do better on 'metallic', inharmonic ones.
Spectrum view: each spike is one partial. The faint grid lines mark perfect whole-number multiples — in harmonic mode the spikes sit on them; in saron mode they land in between.
Under the hood: partials, harmonics & inharmonicity
A harmonic sound has partials at frequencies fk = k·f0 for k = 1, 2, 3… The common period is 1/f0, so the waveform is periodic and the ear (and most algorithms) reads f0 as the pitch.
A free bar vibrating transversely (the saron model) has mode frequencies scaling roughly with the square of odd integers, giving ratios near:
Those figures come from Jim Woodhouse's Euphonics §3.2, which lists the free–free bending modes as 1.00, 2.76, 5.40, 8.93, 13.34 and notes that "none of the ratios are very close to whole numbers."
No common divisor → no period → the sum of these sines is quasi-periodic at best. Research on gamelan instruments (McLachlan, Marco & Wilson 2013, Frontiers in Psychology 4:768) shows makers tune the lowest partial precisely — sister instruments within about 2 Hz of each other, while upper partials vary widely — and listeners' perceived pitch tracks it. The upper partials are timbre, not pitch.
Chapter 2 · Family one: time-domain
"Does the wave repeat?"
The first family of methods never looks at frequencies at all. It takes the waveform, slides a copy of it forward in time, and asks: how far do I have to slide before it lines up with itself again? That slide distance is the period, and one-over-the-period is the pitch.
Try it yourself. Drag the slider to slide the ghost copy. On the harmonic sound you'll find spots where the match score jumps toward 100% — that's the wave repeating. Then switch to the saron bar and try to find one.
Method 1 · NSDF / McLeod time-domain
Computes that match score at every lag automatically (the curve above), then picks a peak. Scala Creator's current engine. It picks the tallest peak, because on rich metallic gamelan sounds the true note reliably wins — a deliberate tweak to the textbook recipe. Accurate to about 1 cent on clean tones, cheap enough to run live in the browser.
Method 2 · YIN & pYIN time-domain
The same core idea, measured as mismatch instead of match: it looks for the first lag where the difference dips near zero. pYIN adds a probabilistic layer that smooths a melody over time — great for singing, not much help for one struck note. Both inherit the family weakness: no repetition, nothing to find.
Under the hood: autocorrelation, NSDF & YIN
Autocorrelation multiplies the signal by a delayed copy of itself and sums:
NSDF (the McLeod Pitch Method, from McLeod & Wyvill 2005) normalizes it so the score always lives between −1 and +1 regardless of loudness:
The peak height doubles as a clarity measure — how tone-like the sound is. Canonical MPM picks the first major peak; Scala Creator picks the global maximum, which avoids spurious low-frequency candidates on metallic timbres but is riskier on other material.
YIN (de Cheveigné & Kawahara 2002) instead computes a difference function d(τ), normalizes it cumulatively, and takes the first dip below a threshold (≈0.15). pYIN (Mauch & Dixon 2014) runs it across a distribution of thresholds and Viterbi-decodes the candidates into a smooth track. Published accuracy for both is ±1–2 cents — on harmonic test sets. On inharmonic sounds, the failure isn't precision, it's picking the wrong partial entirely.
Chapter 3 · Family two: frequency-domain
"Where is the energy?"
The second family gives up on repetition entirely. It runs the sound through a Fourier transform — the same math behind every EQ display — and simply reads where the spectral peaks are. No repeating waveform required. For a gamelan bar, the lowest strong peak is the pitch the maker tuned and the ear hears.
Explore the spectra below. Hover or tap the peaks. Notice the bell: its perceived note (the "strike note") sits where there's no peak at all — your brain invents it from the partials above. That's why no naive rule survives every instrument.
An FFT chops the frequency axis into bins, like pixels. A real partial usually lands between two bins — and for tuning files we need cents-level precision, far finer than the bins. The fix is lovely: fit a curve (a parabola) through the tallest bin and its two neighbours, and read the curve's tip. Drag the slider to move the true frequency around and watch the estimate follow it.
Method 3 · Interpolated FFT frequency-domain
The two panels above, combined: find the lowest strong spectral peak, refine it with the parabola trick. Accuracy well under 1 cent, and it doesn't care whether the sound is harmonic. This is the recommended future engine for Scala Creator's inharmonic uploads. Its one weakness — grabbing an upper partial by mistake — is fenced off with a frequency-range control.
Method 4 · Cepstrum frequency-domain
A clever speech-processing trick: it measures the spacing between spectral peaks. Brilliant when peaks are evenly spaced — which is exactly what harmonic sounds have and gamelan sounds don't. The instructive part is that it doesn't fall silent on a saron: it averages spacings that were never equal and hands back a confident spike at a period no partial has. Included here as the wrong tool, and as a lesson in output that looks like an answer.
The cepstrum doesn't look for peaks — it looks for the rhythm of the peaks. Evenly spaced partials make the spectrum ripple, and that ripple shows up here as one tall spike whose position is the period of the note. Switch instruments and watch what happens to the spike. The dashed line marks where it should land if the lowest partial is the pitch.
Under the hood: QIFFT & the cepstrum
The quadratically-interpolated FFT is set out in Julius O. Smith III's Spectral Audio Signal Processing (CCRMA, Stanford). With the peak bin k and its neighbours' dB magnitudes y₋₁, y₀, y₊₁, the parabolic offset from the bin centre is:
With zero-padding, error drops below 0.1% of frequency — sub-cent for a clean partial. One practical note: the Web Audio AnalyserNode's default FFT is far too coarse for this; a custom zero-padded FFT is required.
The cepstrum is the inverse FFT of the log-magnitude spectrum. Evenly spaced harmonics create a ripple in the log spectrum whose "frequency" (called quefrency) equals the pitch period — it shows up as one sharp cepstral peak. Uneven inharmonic partials produce no coherent ripple — but note what that does not mean. The transform still returns something: a peak at whatever period best fits mutually incompatible spacings, or, where partials are near-integer multiples, a peak at a genuine periodicity that isn’t the perceived pitch. Absence of structure produces a wrong reading, not a blank one, which is why the panel above is worth switching through.
Chapter 4 · The outsider
Method 5 · CREPE, the neural network
CREPE belongs to neither family. It's a deep neural network that was shown millions of examples of pitched audio with known answers, and learned to guess. For each slice of sound it lights up a row of 360 pitch "bins", each 20 cents wide — its confidence for every possible note.
Why it's tempting data-driven
State-of-the-art accuracy on voices and harmonic instruments — 99.5% of frames within 10 cents on its RWC-Synth benchmark (Kim, Salamon, Li & Bello 2018). Astonishing on the material it was trained on.
Why it's not the engine data-driven
It never studied for this exam: the training data contains essentially no inharmonic idiophones, and its own authors note "noisy results for uncommon instruments." Its bins are 20 cents wide — coarse for tuning work — and the full model is ~89 MB, heavy for a browser. Verdict in the notes: an optional, clearly-labelled cross-check. Never the source of truth for a tuning file.
Chapter 5 · The payoff
The showdown: five methods, four instruments
Pick an instrument, listen to it, then reveal how each method fares. The verdicts below are a scripted illustration — a summary of the research and testing behind Scala Creator, not a live computation — but every sound you hear is really synthesized from the physics ratios of that instrument.
| Method | Verdict | Why |
|---|
Under the hood: where the verdicts come from
Saron bars, genders and slenthems vibrate like free bars (modal ratios ≈ 1 : 2.76 : 5.40 : 8.93, per Woodhouse, Euphonics §3.2); McLachlan, Marco & Wilson (2013) show makers tune the lowest partial to within ~2 Hz across an ensemble while upper partials vary widely — so "lowest strong partial" is the physically and perceptually correct target.
A bossed gong's central boss forces two principal modes into a near-2:1 relationship (Rossing & Shepherd, "Acoustics of gamelan instruments," Percussive Notes 1982), and on some gongs the pitch-bearing partial is the 2nd or 3rd — which is why the spectral method needs a frequency-range fence rather than a blind "lowest peak" rule.
A bell's strike note is a virtual pitch: the ear constructs it from the nominal, superquint and octave-nominal partials, landing near nominal ÷ 2 — a frequency where there may be no partial at all. Bill Hibbert's The Sound of Bells documents the effect and the measurements behind it. Every naive method misses it; handling bells needs a dedicated strike-note mode.
The spectral-matching alternative to all of this is SWIPE (Camacho & Harris 2008), which fits a sawtooth template to the spectrum — a reasonable middle ground, though still harmonic-template-based and so not ideal for strongly inharmonic material.
Full citations and the complete engineering plan live in PITCH_DETECTION_NOTES.md.