Notes, scales
& chords
Music isn't a mystery — it's arithmetic you can hear. A handful of frequency ratios, repeated, give you every melody and every chord ever written. Here we build that grammar from one note, by hand, and play it.
Why these notes, and not others?
In How Synths Make Sound you learned that pitch is frequency, and that the ear hears ratios, not raw hertz. You even met the formula f(n) = 440·2^((n−69)/12) in passing. This lesson is where that formula stops being a footnote and becomes the entire grammar of melody and harmony.
Out of the infinite continuum of frequencies, every keyboard on Earth picks the same twelve per octave. That choice isn't arbitrary and it isn't quite "natural" either — it's a beautiful engineering compromise, and once you see the compromise, the whole system clicks into place.
We'll answer three questions, each one building the next: why the octave? (Chapter 1), why twelve steps? (Chapters 2–3), and how do we stack those steps into scales and chords? (Chapters 4–5). Then you'll play the answer.
The octave as the ratio 2:1; equal temperament and the semitone r = 2^(1/12) derived properly; intervals as ratios and the comma that forces the compromise — worked by hand; scales as step patterns; chords as stacked thirds with the 4:5:6 ratio worked out for A major; and a playable keyboard that lights any scale and any chord you ask for.
Double the frequency, "same" note.
Sing any note, then sing "the same note, higher." What you naturally land on is double the frequency. A woman and a man singing "happy birthday together" are usually an octave apart and we hear them as singing the same tune, not two different ones. That's the deepest fact in all of music:
Why that ratio and not, say, 1.9 or 2.1? Recall harmonics from the synth lesson: a note at f already contains overtones at 2f, 3f, 4f…. The note an octave up at 2f shares every one of its harmonics with the lower note — the overtones line up perfectly. Two notes whose harmonics overlap that completely fuse in the ear. The octave isn't a convention; it's harmonic coincidence.
Anchoring the system at A4 = 440 Hz, octaves of A march off in both directions by doubling and halving:
n = 69).Mathematician: the octave is a doubling, a factor of 2 in frequency — the simplest non-trivial ratio there is. Musician: it's the strongest consonance, two notes so alike we give them the same letter name (A and A). Artist: it's a frequency folded back onto itself — the spiral of pitch making one full turn and landing on its own colour again.
Cut the octave into twelve equal multiplications.
The octave gives us a frequency and its double. To make melodies we need stepping stones in between. Western music splits each octave into twelve equal steps called semitones — the smallest move on a piano, from any key to the very next one (white or black).
"Equal" has to mean equal to the ear, and the ear hears ratios — so each semitone must multiply the frequency by the same factor r. Twelve of those multiplications, stacked, must land exactly on the octave (×2). That single sentence pins down r completely:
f reach f · r12, and that must equal the octave 2f.r12 = 2 — the step factor, raised to the twelfth power, is a doubling.r = 21/12, the twelfth root of two ≈ 1.05946. Each semitone is +5.946% in frequency.This is equal temperament (ET) — the tuning every modern keyboard uses. Notice the genius of it: because the ratio between any two adjacent notes is identical, a melody sounds the same whether you start it on C or on F♯. You can transpose freely. That portability is exactly why pianos are tuned this way. Let's grind out a few notes by hand to see the formula is just multiplication:
| Note | MIDI n | Calculation | Frequency |
|---|---|---|---|
| A3 | 57 | 440 · 2−12/12 = 440 · ½ | 220.00 Hz |
| C4 (middle C) | 60 | 440 · 2−9/12 | 261.63 Hz |
| C♯4 | 61 | 261.63 · r | 277.18 Hz |
| E4 | 64 | 440 · 2−5/12 | 329.63 Hz |
| A4 | 69 | 440 · 20 | 440.00 Hz |
Check the step from C4 to C♯4: 261.63 × 1.05946 = 277.18 Hz ✓. Every adjacent pair on the keyboard is that same multiply. Here it is in code — and it's the same midiToFreq the keyboard you'll play below calls on every keypress:
// any MIDI note → a frequency the oscillator can play const midiToFreq = n => 440 * 2 ** ((n - 69) / 12); midiToFreq(69); // 440.00 → A4 midiToFreq(60); // 261.63 → middle C midiToFreq(61) / midiToFreq(60); // 1.05946 → exactly r, one semitone
import numpy as np def midi_to_freq(n): return 440.0 * 2 ** ((n - 69) / 12) r = 2 ** (1 / 12) # 1.0594630943592953 — the semitone factor print(r ** 12) # 2.0000000000000004 — twelve steps = one octave
Why ET is a compromise — the comma, worked out.
An interval is the distance between two notes, and in the ear it's a ratio. Some ratios sound sweetly consonant because they're simple — small whole-number ratios make harmonics line up, just like the octave's 2:1 did. The two most important after the octave:
The perfect fifth — seven semitones — wants to be the just ratio 3:2 = 1.5. The major third — four semitones — wants to be 5:4 = 1.25. "Just intonation" tunes notes to exactly these whole-number ratios. But equal temperament uses powers of r instead. How close does it get?
r7 = 27/12 = 1.49831. Just fifth = 3/2 = 1.50000. ET is flat by 0.00169 — about 2 cents, utterly inaudible.r4 = 24/12 = 1.25992. Just third = 5/4 = 1.25000. ET is sharp by ~14 cents — slightly audible, the one real cost of ET.1/1200 of an octave, i.e. 21/1200 per cent. The fifth's error 1200·log₂(1.49831/1.5) ≈ −1.96 cents; the third's 1200·log₂(1.25992/1.25) ≈ +13.7 cents.So why not just use the pure 3:2 fifths everywhere? Because of a famous catastrophe. Stack twelve pure fifths (multiplying by 3/2 twelve times) and you should arrive back at the same note, seven octaves up. Watch what actually happens — this is the Pythagorean comma:
(3/2)12 = 531441 / 4096 ≈ 129.746.27 = 128.000. They should match… they don't.129.746 / 128 ≈ 1.01364, about +23.5 cents. Pure fifths overshoot the octave by nearly a quarter-semitone.Here are the workhorse intervals, each as ET vs the just ratio it approximates. The bar length is the ratio; consonance lives in the simple fractions:
Mathematician: simple integer ratios (3:2, 5:4) are consonant, but no power of 2^(1/12) equals them exactly — and twelve 3:2s miss seven octaves by the comma. Musician: ET trades a tiny, even out-of-tuneness for the freedom to play in any key on one instrument. Artist: the comma is a spiral that almost closes — chase pure fifths and you never quite return home; ET nudges the path so the loop seals.
A scale is a pattern of steps.
Twelve notes per octave is the full palette — the chromatic scale, all steps of size 1. But melodies almost never use all twelve. A scale is a chosen subset, defined by its pattern of semitone steps. Pick a starting note (the root or tonic) and walk the pattern.
The major scale — the "do-re-mi" — is the step pattern 2-2-1-2-2-2-1. Start on C and apply it:
+1 half-steps (E→F and B→C) are exactly the spots with no black key between the whites — which is why C major is "all the white keys." The pattern, not the letters, is the scale.Swap the pattern and you swap the mood. The natural minor scale is 2-1-2-2-1-2-2 — the lowered third gives it its darker colour. The major pentatonic drops the two "tense" notes to leave five: 2-2-3-2-3 — the reason it's almost impossible to hit a wrong note jamming on the black keys.
Building a scale in code is just a running sum of the step pattern, turned into frequencies — and this is exactly what the keyboard below does to decide which keys to light:
const midiToFreq = n => 440 * 2 ** ((n - 69) / 12); function buildScale(rootMidi, steps) { const notes = [rootMidi]; let m = rootMidi; for (const s of steps) { m += s; notes.push(m); } // running sum of steps return notes.map(midiToFreq); // → frequencies, low → high } const MAJOR = [2, 2, 1, 2, 2, 2, 1]; buildScale(60, MAJOR); // C major: [261.63, 293.66, 329.63, 349.23, 392, 440, 493.88, 523.25]
import numpy as np def build_scale(root_midi, steps): midi = np.cumsum([root_midi, *steps]) # running sum of the step pattern return 440.0 * 2 ** ((midi - 69) / 12) # MIDI → Hz, vectorised MAJOR = [2, 2, 1, 2, 2, 2, 1] build_scale(60, MAJOR) # array([261.63, 293.66, 329.63, 349.23, 392., 440., 493.88, 523.25])
Stack thirds. The harmonics agree.
A chord is several notes sounded at once. The most fundamental is the triad: a root, a third, and a fifth — built by stacking thirds. A major triad stacks a major third (4 semitones) then a minor third (3 more), so its notes sit at offsets 0, 4, 7 from the root.
Why does a triad sound stable and sweet? Because those three notes' frequencies form a near-perfect small-integer ratio — and small integers mean overlapping harmonics. Let's work out A major (A–C♯–E) exactly:
440 · r4 = 440 · 1.25992 = 554.37 Hz. Ratio to root: 554.37/440 = 1.2599 ≈ 5:4.440 · r7 = 440 · 1.49831 = 659.26 Hz. Ratio to root: 659.26/440 = 1.4983 ≈ 3:2.440 : 554.37 : 659.26 = 1 : 1.25 : 1.5 = 4 : 5 : 6. The major triad is the ratio 4:5:6 — three of the lowest harmonics of one phantom fundamental.The minor triad just flips the order of the stacked thirds — minor third first (3 semitones), then major (4) — giving offsets 0, 3, 7 and the ratio 10:12:15. The single semitone difference between the major third (+4) and the minor third (+3) is the entire difference between "happy" and "sad." A dominant 7th adds one more third on top (offset +10) for the ratio 4:5:6:7 — the bluesy, unresolved sound.
Playing a chord in code is just spawning several voices at once — exactly what the keyboard's chord buttons do under the hood:
const midiToFreq = n => 440 * 2 ** ((n - 69) / 12); const CHORDS = { maj: [0, 4, 7], min: [0, 3, 7], dom7: [0, 4, 7, 10] }; function playChord(rootMidi, kind) { return CHORDS[kind].map(off => { const v = window.RVA.voice({ type: 'triangle', freq: midiToFreq(rootMidi + off) }); window.RVA.on(v, 0.22); // fade each voice in → they sound together return v; // keep the handles so you can .off() them later }); } playChord(69, 'maj'); // A major: 440, 554.37, 659.26 Hz — the 4:5:6 triad, audible
import numpy as np def chord_freqs(root_midi, offsets): midi = np.array(offsets) + root_midi return 440.0 * 2 ** ((midi - 69) / 12) fs = 44100; t = np.arange(fs) / fs freqs = chord_freqs(69, [0, 4, 7]) # A major → [440., 554.37, 659.26] x = sum(np.sin(2 * np.pi * f * t) for f in freqs) # add the three sines → one chord signal x /= np.max(np.abs(x)) # normalise to avoid clipping
You just summed three sines into one signal — that tangled x is a chord. The DFT lesson's chord analyzer does the reverse: hand it that mixed signal and the Discrete Fourier Transform pulls the three frequencies back out and names them A, C♯, E. A chord is several frequencies at once — synthesis stacks them, the DFT un-stacks them. Same machine, opposite directions.
Now play the grammar.
Everything you derived is wired into this one keyboard. Click or drag across the keys to play — the readout shows each note's name, its exact frequency from f(n), and its interval ratio from the root. Pick a scale and only its notes light up (a teal cap marks the root). Press a chord button and its tones glow and sound together — the very 4:5:6 you worked out. Change the root to transpose the whole thing, equal temperament doing its quiet magic.
Music (Ableton): you play it with your hand and it sounds musical because the scale filters out the wrong notes. Math (Stanford): every key is f(n) = 440·2^((n−69)/12), every interval a power of r, every chord a small-integer ratio — the keyboard is a stained-glass picture of equal temperament. Art (Nature of Code): the scale paints the octave, chords bloom as lit columns, presses flash and decay like struck strings. The grammar of music is the arithmetic — you've been doing math the whole time you were making melodies.
From here the Play track grows the music: envelopes shape how each note breathes, LFOs add motion, and chords in time become song structure. And when you cross into the Signal track, the DFT takes the chords you just built here and reads them back out of the air — the exact inverse of the summing you did in Chapter 5. Notes were always frequencies; now you can both write them and recover them.
Back to Reverbs →A scale is a rule, a chord is a ratio, and a melody is arithmetic you can hear.
Xavier Serra et al., Audio Signal Processing for Music Applications (Stanford / UPF, Coursera) — pitch, frequency & the harmonic basis of tuning. · Ableton, Learning Music — notes, scales & chords by ear, the interaction grammar. · Hermann von Helmholtz, On the Sensations of Tone (1863) — the foundational treatment of consonance & just intonation. · MDN, Web Audio API — the engine under the keyboard.