← Back to Blog
ArbitJust IntonationAlgorithmsMusic Theory

How to Make Just Intonation That Doesn't Sound Awful

May 16, 2026 · 10 min read · DonutsDelivery

The Bug In Just Intonation

Just intonation gives you mathematically pure chords. A 3:2 perfect fifth. A 5:4 major third. A 7:4 harmonic seventh. Hold one of those chords and it does something equal temperament physically can't: the partials lock together, beating disappears, and the sound fuses into a single resonant whole.

Then you change chord. And the floor falls out.

The note you held into the next chord — the shared pitch between them — is no longer the same frequency. It has been retuned to fit the new chord's pure ratios, and your ear hears the same melodic note slide a quarter-tone. The wobble is exactly what 12-tone equal temperament was invented to prevent. It is also why, for 400 years, JI has been beautiful in theory and unusable in practice.

Where The Wobble Comes From

Pick a root note. Build the chromatic scale from it using pure JI ratios. The intervals fall at these cents positions, not at the 100-cent grid of equal temperament:

JI chromatic scale, cents from rootC0C#112D204D#316E386F498F#583G702G#814A884A#996B1088C1200

Now shift to a new root — any other pitch in that scale — and rebuild the chromatic scale from that new root. The two scales don't all line up. Specific pitches in the song will land at different cents under different roots, and the difference is the wobble.

This is not a quirk of any particular implementation. It is a structural property of the harmonic series. JI ratios divide the octave unevenly, so the same pitch class lives at slightly different cents under different roots. Here is the full matrix for standard 5/7-limit JI, showing the worst-case drift on any pitch class as you transition between roots:

Drift map: max | cents drift | from-root → to-rootfromCC#DD#EFF#GG#AA#Bto-rootCC#DD#EFF#GG#AA#B041274941274927414927414102727414149412749494127270414927492741492949492741049494941276349494141494904135494927412727412749410352749412741494949493535049493535352741274149274904149274141274127494949410494941494949632741354949041272749294941273527494102741414949274135414127270cents drift:015304560+

Every red cell is a chord change where some pitch in the song will drift audibly. The motion you'd reach for instinctively — C to G, F to C, fifths — is mostly green. The hurt is concentrated in the transitions that make harmony move: borrowed chords, secondary dominants, tritone substitutions, chromatic mediants, and other harmony that moves by something stranger than fourths and fifths.

Why Equal Temperament Won

12-TET solved this by making every pitch class live at one frequency forever. A G is 392 Hz whether you're in C major, E flat major, or A flat minor. There is nothing to drift. The cost is that every chord is slightly out of tune — a 12-TET major third beats audibly because 400 cents isn't 386 — but the consistency means you can modulate anywhere without anything wobbling, and that turned out to matter more than purity.

The standard counter — adaptive JI — picks fresh ratios per chord. Each chord is pure on its own. Each chord change wobbles. We just heard why.

The Whole Problem Is Picking The Root Path

Here is the actual question for any JI-style adaptive system playing real music: which root path makes the active notes in each moment land on the cleanest harmonic ratios, while preventing the pitch identities the listener can track from wobbling?

You can see the tension directly from the drift map. If chord A is rooted at C and chord B comes next, you don't have to root chord B at its obvious bass note. You can anchor it on any pitch in B's note set — and different choices make different notes pure, tense, stable, or exposed to drift. Sometimes the bass is the worst choice. Sometimes a chord tone three notes up is the best one. Sometimes the cleanest answer is a muted virtual root that is never heard at all.

And you can't decide locally. A root that makes one chord beautiful might cause a held melody note to jump in the next zone; a root that avoids that jump might leave the current chord in stale, mediocre JI. The right root for any one zone depends on the sounding notes inside it and on the audible note identities around it. You need to plan a path across the whole song, but the prize is internal harmonic quality, not a root line that refuses to move.

The Algorithm: Best Path Through A Lattice

Arbit's Root Path Tune transform solves this as a dynamic programming problem. The structure:

  1. Slice the song into harmonic zones — every span where the active set of sounding notes is stable. Boundaries fall at note onsets and offsets, but note starts can be grouped on an analysis-only grid so humanized chord attacks are understood as one musical event without moving the real MIDI notes.
  2. Enumerate candidate roots per zone — every note sounding in that zone can be a candidate. Arbit can also create muted virtual roots when no audible note gives the chord a clean enough harmonic explanation.
  3. Score every candidate by asking what the sounding notes become when slaved to that root. The important reward is not "does this root avoid moving?" but "does this root make the active chord internally simple and resonant?"
  4. Find the optimal path through the lattice. Viterbi keeps the best accumulated score into each candidate root, then backtracks from the best final state. That means the transform can make local chord decisions while still seeing the whole song.
Viterbi search: one path chosen out of 1024 candidateszone 1zone 2zone 3zone 4zone 5GECBb

The lattice picture shows what "doing all that computing" actually means. Every column is a zone. Every node is a candidate root. Every faint line is a possible transition. For a four-minute song with a hundred zones and five candidates each, the algorithm is choosing between something on the order of 5100 paths — and finds the optimal one in time linear in the number of zones, because Viterbi only needs to remember the best path into each candidate node, not enumerate all paths through.

The Cost That Actually Matters

The audible goal is not to keep the root path still. The root is only a tuning anchor. What the listener hears is the tuned relationship between the notes inside each zone. So the modern Root Path Tune objective gives a positive reward to roots that make the active notes land on simple harmonic ratios.

A useful way to score that simplicity is Tenney height. For a reduced ratio p/q, the height is H(p/q)=log2(p*q). Lower height means smaller integers, stronger harmonic fusion, and usually a more consonant sound. A 3:2 fifth scores better than a 5:4 major third; a 4:3 fourth scores close to the fifth; complex ratios score lower unless the selected tuning system explicitly wants that color.

RatioIntervalTenney heightRoot reward
1:1unison / octave-equivalent0.00strongest
3:2perfect fifth2.58very strong
4:3perfect fourth3.58very strong
5:3major sixth3.91strong
5:4major third4.32strong
6:5minor third4.91moderate
7:5septimal tritone color5.13contextual
9:8whole tone6.17weak
16:15minor second7.91lowest

In code, the candidate root gets something like:

slavePleasure(zone, root) = sum(noteSalience * consonanceReward(bestRatio(note, root)))

The best ratio comes from the active interval set, so this is not hard-coded to one fixed JI table. A custom tuning palette still uses the same principle: intervals with simpler, closer harmonic ratios receive more reward; more complex ratios are used when they explain the written notes better or create the intended color.

Drift Is A Guardrail, Not The Prize

Early versions weighted root-to-root smoothness too heavily. That made the optimiser choose roots that were merely "not terrible" across long spans. It avoided motion, but it could also leave whole sections in stale just intonation instead of choosing the local root that made each chord ring.

The newer model treats root motion as normal. There is no inherent penalty just because the root changed. The penalty is for audible pitch identity drift: a held note, repeated melody tone, doubled instrument, or exposed common tone changing frequency enough that the listener hears it slide or beat against itself.

That distinction matters. If no note identity carries across the boundary, changing root is usually good: it lets the next chord choose the anchor that gives the cleanest internal ratios. If the same E is sustained into the next zone, the algorithm asks whether tuning it under the new root would move it audibly. Drift is measured on sounding notes, not on abstract root names.

Virtual Roots And Consolidation

Sometimes the best harmonic explanation is not one of the notes currently sounding. Arbit can create a muted virtual root: an anchor note that is never played, but lets the audible chord be linked to a cleaner set of ratios. This is how a chord can be optimized for both internal consonance and smooth motion from the previous zone.

Virtual roots are kept local. If a generated muted root has the same actual frequency as an adjacent real root, it is redundant and can be removed; the zone simply uses the real root. If several generated roots form a contiguous run at the same frequency next to a real note, the whole run can collapse into that real note. The transform does not search the entire song for matching frequencies, because that would create links across unrelated musical regions. Consolidation only happens across adjacent zones where the musical context is continuous.

The Tradeoff That Stays

Pure JI and stable common tones are not always simultaneously achievable. A song with heavy chromatic motion across pitches that share no clean JI relationship will force the optimiser to pick the least-bad path; some drift will remain, just much less of it, and concentrated on the places where the ear notices least. Equal temperament avoids the problem by giving up purity entirely. Root Path Tune negotiates the tradeoff per song, per zone, against the constraint that whatever you hear at a chord change is the smallest possible compromise from both sides.

This is not a magic eraser for a 400-year-old problem. It is an honest redistribution of the cost across the moments where the ear notices least. The held melody note stays where you wrote it. The chords lock into the harmonic series. The chord changes carry whatever drift is mathematically unavoidable, smoothed across the points where the music's rhythm and texture cover it.

Pure harmony has been waiting for the algorithm that makes it move. Arbit ships it.