Press one valve on a trumpet and the note is in tune. Press two and it is sharp. Press three and it is sharp by more than a quarter tone.
Every trumpet player meets this in the first month, as an instruction: pull the third slide for low D and low C#. Nobody is told why, and the why is not acoustics. It is that pitch multiplies and tube adds.
One valve is exactly right
A valve diverts the air through a loop and the horn gets longer. Dropping n semitones means multiplying the horn’s length by 2n/12, so the loop has to add
s(n) = 2^(n/12) − 1 times the horn it is being added to
Cut against the open horn, that is the whole design, and it is exact:
| valve | drops | fraction of the horn | tube | slide |
|---|---|---|---|---|
| 2 | a semitone | 5.9463% | 87.51 mm | 43.75 mm |
| 1 | a tone | 12.2462% | 180.21 mm | 90.11 mm |
| 3 | a tone and a half | 18.9207% | 278.43 mm | 139.22 mm |
(A slide has two legs, so it carries half the tube it adds. Every number in this file comes in both currencies and they are never the same number.)
The open horn here is 1.4716 m, and it is derived rather than looked up: a brass instrument’s playable modes go as n·c/2L for n ≥ 2, and a B♭ trumpet’s second mode is written C4 sounding concert B♭3, so c/L = 233.082 Hz. Against the ~1.48 m of tubing a trumpet actually contains, that is as close as an open pipe has any business getting.
Then you press two
Valve 1’s loop was cut against the open horn. Press valve 3 as well and the horn valve 1 is being added to is 18.9% longer than the horn it was cut for — so it is 18.9% too short, and there is nothing about a piston that could know otherwise.
| fingering | should drop | wants | has | short by | pull | cents |
|---|---|---|---|---|---|---|
| 2 | 1 | 87.51 | 87.51 | — | — | 0.00 |
| 1 | 2 | 180.21 | 180.21 | — | — | 0.00 |
| 3 | 3 | 278.43 | 278.43 | — | — | 0.00 |
| 1–2 | 3 | 278.43 | 267.72 | 10.72 | 5.36 | +10.63 |
| 2–3 | 4 | 382.50 | 365.94 | 16.56 | 8.28 | +15.53 |
| 1–3 | 5 | 492.75 | 458.65 | 34.10 | 17.05 | +30.32 |
| 1–2–3 | 6 | 609.55 | 546.15 | 63.40 | 31.70 | +53.56 |
Written low D is 1–3. Written low C# is 1–2–3. A quarter tone is 50 cents.
The error is four rectangles
Three valves down should multiply:
(1 + s₁)(1 + s₂)(1 + s₃) − 1
Three valves down actually add:
s₁ + s₂ + s₃
Subtract, and nothing is approximated away — what is left is exactly the terms a sum cannot carry:
s₁s₂ + s₁s₃ + s₂s₃ + s₁s₂s₃
| term | fraction | tube | share of the gap |
|---|---|---|---|
| s₁s₃ | 2.31707 × 10⁻² | 34.098 mm | 53.78% |
| s₂s₃ | 1.12508 × 10⁻² | 16.557 mm | 26.12% |
| s₁s₂ | 7.28197 × 10⁻³ | 10.716 mm | 16.90% |
| s₁s₂s₃ | 1.37780 × 10⁻³ | 2.028 mm | 3.20% |
| 63.400 mm |
That is the cross loop: a magnifier pointed at the gap in the bar, and the
four rectangles dropped into it one at a time until they tile it. They tile it
to the last bit of a double, and validate re-checks the identity on every
render for all seven fingerings rather than taking three figures as proof.
It also says which way the error has to go. Every term is a product of positive numbers, so the shortfall is positive for every combination there is — a trumpet with two or three valves down is sharp, never flat, and there is no fingering and no instrument for which that is not true.
And the error is second order, which is the trap
s₁s₃ is 2.3% where s₁ is 12%. Second-order errors are the ones that stay invisible while you design the thing and then arrive all at once:
- two valves that dropped a semitone each: +5.46 cents, which nobody would notice;
- 1 and 3 together, five semitones: +30.3, which a tuner notices;
- all three, six semitones: +53.6, which the audience notices.
So the design is sound exactly as far as the intervals are small, and a trumpet needs six semitones from three valves.
The fix is a slide, and the slide is the design
The pull column above is not advice, it is the solution of
shortfall / 2, and the two numbers in it are the two a player is taught:
17.05 mm for low D. 31.70 mm for low C#.
The pull loop draws it at the frame’s own scale — the loops under the casings
and the bar in the panel are both at 220 px/m, so the slide coming out is the
real 63.40 mm of tube — and then it sends the bill. Leave the slide where low
C# needed it and the horn now has a third valve loop 63.40 mm too long:
| with the slide left out | cents |
|---|---|
| 2–3 (written E♭4) | −43.19 |
| 1–3 (written D4) | −25.63 |
| 3 alone | −61.61 |
Flat by nearly half a semitone, on the note directly above the one you just
fixed. That is the second half of the pull loop, and it is the part that is
actually hard to play: a chromatic run down from E4 wants the slide at
E4 1–2 0.00 mm
E♭4 2–3 8.28 mm
D4 1–3 17.05 mm
C#4 1–2–3 31.70 mm
Four consecutive semitones, three moves, the largest 14.65 mm between two adjacent notes. At 120 bpm in semiquavers that is 117 mm/s of left hand, which is why fast chromatic passages down there are simply played sharp.
You cannot cut your way out of it
Seven fingerings, three lengths. So: what is the best set of three tubes?
optimiseLoops goes and finds out — Nelder–Mead on the weighted sum of squared
cents errors, written out in the module rather than imported, because the point
of the answer is that it was searched for.
Equal weight on all seven (lengthen every loop; spread the damage):
loop 1 +13.29 mm 1:−13.9 2:−5.8 3:−17.1
loop 2 +5.27 mm 12: −7.7 23:−5.7 13: +3.0 123:+23.0
loop 3 +17.38 mm worst 22.99 rms 12.81
Worst case more than halved, from 53.56 to 22.99 — bought by making every single-valve note on the instrument six to seventeen cents flat. Those are the notes you play constantly. This is a worse instrument.
Minimax, the flattest possible worst case:
loop 1 +14.66 mm 1:−15.3 2:−14.0 3:−16.3
loop 2 +12.64 mm 12:−16.3 23:−11.8 13: +2.5 123:+16.3
loop 3 +16.58 mm worst 16.32
16.32 cents. That is the floor. No three tubes exist that bring a three-valve instrument inside a sixth of a semitone, and the set that reaches it equioscillates — three fingerings pinned at ±16.32, which is what tells you the search found the bottom rather than a ledge. (The value is sharp; the lengths that achieve it are not unique, so the objective carries a tie-break.)
Weight it by what you actually play, and something falls out
The honest weighting is not “all seven equally” — it is how often each
fingering is used. So CHART holds the standard chromatic chart from written
F#3 to C6, thirty-one notes, and usageWeights counts it:
1:6 2:6 3:0 1–2:5 2–3:4 1–3:2 1–2–3:2
Valve 3 never appears on its own. Not once in thirty-one notes — the three-semitone drop goes to 1–2, and the third valve spends its entire working life in combination. Hand the optimiser that zero:
loop 1 +7.48 mm (3.74 mm of slide) 1:−7.8 2:−1.4 3:−26.2
loop 2 +1.30 mm (0.65 mm of slide) 12:+1.9 23:−10.6 13: −0.0 123:+23.4
loop 3 +26.67 mm (13.33 mm of slide) rms over the chart: 8.82, against 19.08
It gives loops 1 and 2 under nine millimetres between them — those two carry the notes you actually play, so they have to stay near right — and it lengthens the third loop by 26.67 mm, throwing valve 3 alone 26 cents flat to buy back 1–3 (which lands on −0.04 cents, in tune) and more than half of 1–2–3. The one fingering it sacrifices is the one the chart had already given up on.
Which is the quiet joke in the whole instrument: the chart prefers 1–2 over 3
because the third valve is cut long, and the third valve can be cut long
because the chart prefers 1–2. Both halves are load-bearing and neither is
written down anywhere. The best loop is this set of three tubes, cycling all
seven fingerings so you can watch the needle sit left of zero on everything a
player uses and right of it only where the chart is not looking.
The loops
| loop | frames | what it is |
|---|---|---|
press | 8 | Valve 2 alone. Includes the two mid-stroke frames where the ports line up with nothing and the horn is simply shut — the half-valve, which is a real state and not a drawing shortcut. |
stack | 8 | 1, then 1–3, then 1–2–3. The mechanism does not change; the needle walks 0 → 0 → +30.3 → +53.6. |
pull | 8 | 31.70 mm of third slide, and then E♭4 with the slide still out at −43.2. |
cross | 6 | The four rectangles, revealed one at a time, tiling 63.40 mm exactly. |
best | 7 | The chart-weighted compromise loops, visibly longer, cycling every fingering. |
The demo
Three valves on keys 1/2/3, both slides on sliders, all three loop lengths on sliders, and the four tunings as presets. The chips across the top are all seven fingerings live, so changing a loop shows you what it costs everywhere else at once.
It makes sound. Two voices: what the valves actually give you, and what you were aiming at. 53.56 cents on written C#4 is 247.22 Hz against 254.99 Hz, and the thing you hear is not “sharp”, it is a 7.77 Hz beat. Press 1–2–3, turn the reference on, then hit auto pull and watch the beat stop.
Worth doing on two partials: the same 53.56 cents on written F#3 an octave down beats at 5.18 Hz instead, because cents are a ratio and beats are a difference. A scale-free error with a scale-dependent symptom.
Reuse
source/low-d.mjs is framework-free and has no DOM above the drawing layer.
The arithmetic is separable from the sprite:
import { centsOf, shortfall, slidePull, crossTerms, optimiseLoops,
minimaxLoops, usageWeights, NOMINAL } from './low-d.mjs';
centsOf([0, 2]); // +30.315 — low D
slidePull([0, 1, 2]) * 1000; // 31.70 mm of third slide
crossTerms([0, 1, 2]); // the four, largest first
optimiseLoops(usageWeights()); // the compromise, found not asserted
minimaxLoops(); // the floor: 16.32 cents
nelderMead(f, x0) is a general three-line-of-maths simplex search and knows
nothing about trumpets. facts() is memoised and holds every number quoted
above; node source/render.mjs regenerates every PNG and reprints all of them,
so this file goes stale loudly rather than quietly.
validate() re-proves the load-bearing claims on every render: that each loop
alone is exact, that the gap is the cross terms for all seven fingerings,
that cents are scale-free, that a computed slide pull really does land the note
on zero, that the minimax solution equioscillates, that the compromise is a
genuine stationary point, that the chart really never uses valve 3 alone, and
that a loop’s drawn depth and its share of the bar are the same number of
pixels. node scripts/screenshot-demo.mjs boots the demo in a real browser and
runs 22 assertions against it, four of which read pixels back out of the canvas
rather than trusting the model that painted them.
Gotchas
- Cents are the portable part; millimetres are not. Every cents figure here
is a ratio of lengths and survives any horn. The millimetres are all 1.4716 m
times something, and that 1.4716 m is an open-pipe idealisation.
validatere-runs the cents claims under a rescaling for exactly this reason. - The errors are measured against the horn’s own partial, not against a piano. A brass instrument’s modes are a harmonic series and the scale is not: the third partial is already +1.96 cents of equal temperament before any valve moves, the fifth is −13.69, and the seventh is −31.17, which is why nobody plays it. Adding those to the valve errors would put two different effects in one number. The demo reports the partial’s own offset separately.
- The loops hang below the casings, which is not where they are. On a real trumpet they come off the back and the third slide points forward. Their lengths are to scale and their positions are a side elevation’s compromise.
- A real player bends notes. Lipping is worth a comfortable 20-odd cents, which covers 1–2 and most of 2–3 and is why those two rarely get mentioned. It does not cover 53.56, and nothing here models it.
- What makers actually cut is not measured here. The chart-weighted optimum lands on a third loop 26.67 mm long of nominal, and real third valve loops are built long for the same reason — but that is a consistency, not a measurement. The one number in this file taken from the world is the fingering chart.
- The minimax lengths are not unique. Once three fingerings are pinned at the maximum the rest can move without changing it. The 16.32 is the result; the three lengths printed beside it are one of the sets that reach it, selected by a tie-break so the figure reproduces.
- The half-valve is drawn as fully shut. Mid-stroke a real piston leaks past its ports rather than sealing, which is what makes a half-valve a usable effect instead of a silence. Here it is binary, because the frame’s job is to show that the ports are pointing at nothing.