What is this about?
Recursive just intonation is a novel toy-tuning system that I came up with during my high school physics classes, It’s very easy to predict why it won’t become popular. That said I find it interesting and both mathematically and musically beautiful, so I decided to write this blogpost (listening examples further below).
Equal Temperament vs Just Intonation
Equal temperament gives us one frequency table. Every C# is the same C#, every G is the same G, and every semitone is the same distance from the last one. That is very convenient, at the cost of slightly altering almost every interval. The intervals are close enough to simple ratios that they work, but all of them are not exact.
Just intonation goes the other way. It treats notes as relationships to a root, then builds those relationships from simple frequency ratios:
- octave:
2/1 - perfect fifth:
3/2 - major third:
5/4 - major chord:
4:5:6, or1/1,5/4,3/2
Those ratios sound still and locked-in because their waveforms repeat against
each other quickly. In a just major chord, the consonance comes directly from
the exact 4:5:6 relationship.
12-TET
In 12-tone equal temperament, the ratio between adjacent semitones is:
2^(1/12) = 1.059463...The frequency of a note n semitones above some reference note is:
frequency(n) = reference * 2^(n/12)The nice property is composability:
2^(1/12) * 2^(1/12) = 2^(2/12)Going up two semitones one step at a time lands at the same frequency as jumping up two semitones directly. This is why transposition is easy in equal temperament. There is only one global grid.
Just Intonation
The annoying part is that just intonation normally needs a root. A 5/4 major
third above C is E. A 5/4 major third above E is G#/Ab. Those two facts cannot
both fit into one fixed 12-note keyboard unless we allow the same pitch name to
mean different frequencies in different harmonic contexts.
For a C-based just-intonation scale, the usual 12 pitch classes are the
five-limit ones. Every ratio in the table is made of octaves (2), perfect
fifths (3/2) and major thirds (5/4), so no prime above 5 appears in it:
| pitch | ratio from C | built from | from 12-TET |
|---|---|---|---|
| C | 1/1 | 1 | 0.0¢ |
| C#/Db | 16/15 | 4/3 ÷ 5/4 | +11.7¢ |
| D | 9/8 | 3/2 × 3/2 ÷ 2 | +3.9¢ |
| D#/Eb | 6/5 | 3/2 ÷ 5/4 | +15.6¢ |
| E | 5/4 | 5/4 | -13.7¢ |
| F | 4/3 | 2 ÷ 3/2 | -2.0¢ |
| F#/Gb | 64/45 | 16/15 × 4/3 | +9.8¢ |
| G | 3/2 | 3/2 | +2.0¢ |
| G#/Ab | 8/5 | 2 ÷ 5/4 | +13.7¢ |
| A | 5/3 | 4/3 × 5/4 | -15.6¢ |
| A#/Bb | 16/9 | 4/3 × 4/3 | -3.9¢ |
| B | 15/8 | 3/2 × 5/4 | -11.7¢ |
| C | 2/1 | 2 | 0.0¢ |
This already makes a C major chord exact:
C = 1/1
E = 5/4
G = 3/2But an E major chord on the same fixed C just keyboard has a problem:
E = 5/4
G#/Ab = 8/5
B = 15/8Relative to E, the G#/Ab is:
(8/5) / (5/4) = 32/25 = 1.28A just major third should be 5/4 = 1.25. So the E major chord has a fifth that
works and a third that is too high by about 41.1 cents. That is not a tiny
rounding error. It is enough to make the chord feel tense.
The table’s G#/Ab is an Ab: a major third below C. From E, an Ab is a diminished fourth, not a major third. The G# that E major needs is a major third above E, and a fixed 12-note keyboard has no key left for it.
What The Waves Look Like
Nice mathematical ratios are pleasant to our ears.
x + 2*x, where x is some frequency, sounds nice because it has a short
period:
f and 2f. The whole pattern repeats every 1/f seconds, so the ear can lock onto it easily.While, for example, x + 13/12*x has a much longer period:
f and 13/12 f. The combined wave needs 12/f seconds to repeat, so it takes much longer to settle than the octave example.A just major chord is 4:5:6, or 1:1.25:1.5. In 12-TET, the same chord is
closer to 500:630:749, or 1:1.260:1.498.
4:5:6 ratios, while the 12-TET version uses the familiar piano/guitar approximation. They are close, but the 12-TET peaks do not quite return to the same places.12 Just Pianos | Recursive Just Intonation
Here is what I call recursive just intonation:
Keep the roots on a C-based just-intonation keyboard, but give every chord root its own just-intonated keyboard.
I think of it as 12 pianos: one just piano rooted on C, one on C#/Db, one on D, and so on. The root of each piano is taken from the original C just-intonation scale. Once a chord chooses a root, all of its notes come from the piano rooted on that note.
This is “recursive” in the simple algorithmic sense: use a just-ratio table to choose the chord root, then use the same ratio table again inside that root.
For an E major chord:
E = C * 5/4
G#/Ab = E * 5/4 = C * 25/16
B = E * 3/2 = C * 15/8Now the E major chord is internally just:
E : G# : B = 1 : 5/4 : 3/2 = 4 : 5 : 6The cost is that G#/Ab is no longer globally stable. Fixed-C just intonation
puts G#/Ab at 8/5 from C. Recursive just intonation puts the G#/Ab inside E
major at 25/16 from C.
fixed C just G#/Ab = 8/5 = 1.6
recursive E-major G# = 25/16 = 1.5625Those are different frequencies sharing the same name.
The general formula is:
recursive_frequency(root, degree) =
C_frequency * J[root] * J[degree]where J[x] is the just-ratio table above, with octave correction whenever the
index crosses C again.
The table below is the “12 pianos” idea written out as frequencies. To keep the
numbers concrete, I set the C root to 130.813 Hz.
How to read it:
- The left column chooses the chord root, or “which piano” you are using.
- The top row chooses the interval above that root. These are ratios, not note names.
- The cell tells you the frequency to play for that local interval.
- The color and small label inside the cell show the resulting pitch name. Cells with the same pitch name share a color.
- The cents line shows how far that frequency is from 12-TET for the same pitch name.
For example, an E major chord uses the E row and the 1/1, 5/4, and 3/2
columns. That gives 163.516 Hz, 204.395 Hz, and 245.274 Hz. In another
octave, multiply or divide the whole row by 2.
| local root | C | C#/Db | D | D#/Eb | E | F | F#/Gb | G | G#/Ab | A | A#/Bb | B |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| C | 130.813 Hz0.000 cents | 139.534 Hz11.731 cents | 147.164 Hz3.910 cents | 156.975 Hz15.641 cents | 163.516 Hz-13.686 cents | 174.417 Hz-1.955 cents | 186.045 Hz9.776 cents | 196.219 Hz1.955 cents | 209.300 Hz13.686 cents | 218.021 Hz-15.641 cents | 232.556 Hz-3.910 cents | 245.274 Hz-11.731 cents |
| C#/Db | 261.626 Hz0.000 cents | 139.534 Hz11.731 cents | 148.836 Hz23.463 cents | 156.975 Hz15.641 cents | 167.440 Hz27.373 cents | 174.417 Hz-1.955 cents | 186.045 Hz9.776 cents | 198.448 Hz21.508 cents | 209.300 Hz13.686 cents | 223.254 Hz25.418 cents | 232.556 Hz-3.910 cents | 248.060 Hz7.821 cents |
| D | 261.626 Hz0.000 cents | 275.933 Hz-7.821 cents | 147.164 Hz3.910 cents | 156.975 Hz15.641 cents | 165.560 Hz7.820 cents | 176.597 Hz19.551 cents | 183.955 Hz-9.776 cents | 196.219 Hz1.955 cents | 209.300 Hz13.686 cents | 220.747 Hz5.865 cents | 235.463 Hz17.596 cents | 245.274 Hz-11.731 cents |
| D#/Eb | 261.626 Hz0.000 cents | 279.067 Hz11.731 cents | 294.329 Hz3.910 cents | 156.975 Hz15.641 cents | 167.440 Hz27.373 cents | 176.597 Hz19.551 cents | 188.370 Hz31.283 cents | 196.219 Hz1.955 cents | 209.300 Hz13.686 cents | 223.254 Hz25.418 cents | 235.463 Hz17.596 cents | 251.161 Hz29.328 cents |
| E | 261.626 Hz0.000 cents | 272.527 Hz-29.328 cents | 290.695 Hz-17.596 cents | 306.592 Hz-25.418 cents | 163.516 Hz-13.686 cents | 174.417 Hz-1.955 cents | 183.955 Hz-9.776 cents | 196.219 Hz1.955 cents | 204.395 Hz-27.373 cents | 218.021 Hz-15.641 cents | 232.556 Hz-3.910 cents | 245.274 Hz-11.731 cents |
| F | 261.626 Hz0.000 cents | 279.067 Hz11.731 cents | 290.695 Hz-17.596 cents | 310.075 Hz-5.865 cents | 327.032 Hz-13.686 cents | 174.417 Hz-1.955 cents | 186.045 Hz9.776 cents | 196.219 Hz1.955 cents | 209.300 Hz13.686 cents | 218.021 Hz-15.641 cents | 232.556 Hz-3.910 cents | 248.060 Hz7.821 cents |
| F#/Gb | 264.597 Hz19.553 cents | 279.067 Hz11.731 cents | 297.672 Hz23.463 cents | 310.075 Hz-5.865 cents | 330.746 Hz5.866 cents | 348.834 Hz-1.955 cents | 186.045 Hz9.776 cents | 198.448 Hz21.508 cents | 209.300 Hz13.686 cents | 223.254 Hz25.418 cents | 232.556 Hz-3.910 cents | 248.060 Hz7.821 cents |
| G | 261.626 Hz0.000 cents | 279.067 Hz11.731 cents | 294.329 Hz3.910 cents | 313.951 Hz15.641 cents | 327.032 Hz-13.686 cents | 348.834 Hz-1.955 cents | 367.911 Hz-9.776 cents | 196.219 Hz1.955 cents | 209.300 Hz13.686 cents | 220.747 Hz5.865 cents | 235.463 Hz17.596 cents | 245.274 Hz-11.731 cents |
| G#/Ab | 261.626 Hz0.000 cents | 279.067 Hz11.731 cents | 297.672 Hz23.463 cents | 313.951 Hz15.641 cents | 334.881 Hz27.373 cents | 348.834 Hz-1.955 cents | 372.090 Hz9.776 cents | 392.438 Hz1.955 cents | 209.300 Hz13.686 cents | 223.254 Hz25.418 cents | 235.463 Hz17.596 cents | 251.161 Hz29.328 cents |
| A | 261.626 Hz0.000 cents | 272.527 Hz-29.328 cents | 290.695 Hz-17.596 cents | 310.075 Hz-5.865 cents | 327.032 Hz-13.686 cents | 348.834 Hz-1.955 cents | 363.369 Hz-31.283 cents | 387.593 Hz-19.551 cents | 408.790 Hz-27.373 cents | 218.021 Hz-15.641 cents | 232.556 Hz-3.910 cents | 245.274 Hz-11.731 cents |
| A#/Bb | 261.626 Hz0.000 cents | 279.067 Hz11.731 cents | 290.695 Hz-17.596 cents | 310.075 Hz-5.865 cents | 330.746 Hz5.866 cents | 348.834 Hz-1.955 cents | 372.090 Hz9.776 cents | 387.593 Hz-19.551 cents | 413.433 Hz-7.820 cents | 436.043 Hz-15.641 cents | 232.556 Hz-3.910 cents | 248.060 Hz7.821 cents |
| B | 261.626 Hz0.000 cents | 275.933 Hz-7.821 cents | 294.329 Hz3.910 cents | 306.592 Hz-25.418 cents | 327.032 Hz-13.686 cents | 348.834 Hz-1.955 cents | 367.911 Hz-9.776 cents | 392.438 Hz1.955 cents | 408.790 Hz-27.373 cents | 436.043 Hz-15.641 cents | 459.889 Hz-23.463 cents | 245.274 Hz-11.731 cents |
We now have a chord-contextual tuning system. Pitch classes split according to harmonic function.
What It Sounds Like
I picked a progression that visits chords where fixed-C just intonation has audible trouble. In the recursive version, each chord retunes around its own root.
The first two columns use the same progression: once as pure sine waves, then again with a simple harmonic timbre. The third keeps a sustained C underneath the progression, so the tradeoff between a global reference pitch and chord-local purity becomes easier to hear.
| tuning system | sine wave progression | harmonic timbre progression | C drone progression |
|---|---|---|---|
| 12-TET |
|
|
|
| fixed C just intonation |
|
|
|
| recursive just intonation |
|
|
|
What If The Roots Come From 12-TET?
Another way to build the 12 pianos is to take the row roots from 12-TET, then build a just-intoned scale on top of each one:
hybrid_frequency(root, degree) =
C_frequency * 2^(root / 12) * J[degree]So the root grid keeps equal temperament’s transposition symmetry, while each row still has just local intervals. The tradeoff is that the row roots no longer come from the original C-based just scale; they are the familiar piano frequencies with just chords built on them.
There is also a stripped-down example that alternates a fixed-C pitch with its recursive chord-local version, then plays both at once so the beating is easier to hear:
more audio examples:
Some split points:
| chord context | note | fixed C JI | recursive JI | difference |
|---|---|---|---|---|
| E major | G#/Ab | 209.300 Hz | 204.395 Hz | -41.059 cents |
| A major | C#/Db | 279.067 Hz | 272.527 Hz | -41.059 cents |
| D major | F#/Gb | 186.045 Hz | 183.955 Hz | -19.553 cents |
| D major | A | 218.021 Hz | 220.747 Hz | +21.506 cents |
Why This Is Nice
The nice part is that every major chord can be made into a clean 4:5:6
relationship, even if the chord root is not C. E major does not inherit C’s
G#/Ab; it gets its own G#/Ab. D major does not inherit C’s A; it gets its own A,
a syntonic comma (81/80) higher.
That lines up with how I hear harmony. When a chord arrives, the ear can accept the chord root as a local center. Recursive just intonation uses that local center instead of constraining every chord to one global keyboard.
It is also a useful programming model. A chord can be rendered as:
root_frequency = base_frequency * global_just_ratio[root]
note_frequency = root_frequency * local_just_ratio[chord_degree]The same pure function works for any root.
Why This Is Bad
The bad part shows up as soon as the chord changes: the same note name can move.
In 12-TET, G#/Ab is one frequency per octave. In fixed C just intonation, G#/Ab is also one frequency per octave, just a different one. In recursive just intonation, G#/Ab depends on why you are playing it.
A few consequences of that:
- A melody can shift pitch if a held note is reinterpreted by the next chord.
- Enharmonic spelling starts to matter, but a 12-key interface usually hides it.
- Modulation requires balancing smooth voice-leading against pure local chords.
- Instruments with fixed frets, keys, or holes cannot do this without pitch bending or multiple samples per pitch class.
So this is not a replacement for equal temperament. Equal temperament is still the practical compromise that lets every key share one physical instrument.
Practical Uses
One day I will make a keyboard on which with your left hand you can determine the current key/context and with your right hand you play notes that are dynamically retuned according to the table, until then the practical applications remain few.
My Other Music Work
- Play around with different tuning systems and your computer keyboard
- Visualize and listen to polyrhythms
- music21-rs
Comments0
Nothing here yet. Select any part of the page to quote it, or just start writing.
Add a comment
Comments are files in the repository. Writing one here opens a pull request against float3/float3.github.io, and it appears on the page once that is merged
the issue this will open
Fork it first. Automatically forking the Repo on edit does not currently work (known issue according to support) and produces 'unknown error'.