The brass learns to buzz again: the timbre probe put trumpet, trombone, tuba, muted trumpet, french horn and brass section down in the dark rows of the new picker next to the woodblocks, which read as a layout bug until the spectrum said otherwise — a trumpet at C4 was putting 90% of its power in its fundamental band with the harmonics essentially absent, and wg_loop_damp, the per-instrument brightness knob the program table is built around, moved the result by 0.1% between 0.00 and 0.30. That last number is the tell: nothing was recirculating for a bore-loss filter to act on. Two causes, both in the LIP branch's rebuild. The lip-resonance biquad was being ADDED to the loop signal — pole radius 0.997 with b0 = (1-r) gives it unity gain, narrowband, centred exactly on the played note, so what was labelled "brass buzz brightening" was a fundamental booster; it now shapes the EXCITATION, where STK's Brass puts it (lipFilter.tick(deltaPressure)). And the valve was starved: written out, into_bore = refl*(1 - lipRefl) + lipRefl*Pm, so wg_reed_offset is the round-trip LOSS, and the 0.6 inherited from the reed branch — where the same field means something else — threw away 60% of the bore per pass and left the upper partials nowhere to live. Mouth pressure was squashed too, (0.22 + 0.05*wg_breath_max) mapping the whole brass range 2.7-3.2 into 0.36-0.38, a fifth of the way into the reed table's active region and well inside the linear stretch of the waveshapers below, so the tanh and the cubic that are supposed to make the brass edge were barely bending. (Its comment called wg_breath_max "a loudness lever applied at the output"; for LIP the field is used nowhere else, so it was only ever the bore drive.) Offset now 0.30, buzz slope -3.0, pressure scaled rather than squashed, lip gain 0.04 → 0.01 because a heavier hand on the excitation narrows the drive toward f0 and costs harmonics. master
Opening the loop back up re-awoke exactly the failure the rebuild existed to prevent, so the fix is not the tuning but the pair of guards around it. A short high-register bore driven at full pressure overblows into a higher regime: notes around D5-G5 landed twelve to sixteen semitones sharp. Raising the bore loss with pitch is physical — a real bore's wall and radiation losses climb with frequency — but on its own it never fixed it, 6 to 10 notes in 792 still jumped at every loss slope tried. Tapering the drive with pitch fixed it at every taper tried. Both are kept, at loss slope 0.70 and taper 0.80, chosen for two-dimensional margin rather than for the peak: the boundary is chaotic (0.40/0.50 fails while 0.20/0.50 and 0.70/0.50 pass), so a lucky point is worth nothing and only a neighbourhood whose neighbours also pass is worth shipping. Measured over 44 semitones x 6 seeds x 6 voices with production jitter on: upper-partial energy 27.5-32.8% against a 9.8-12.5% baseline, Bark centroid 3.33-3.44 → 3.97-4.45, worst pitch error +100 cents → within +/-25, and zero notes off by more than 50 cents where there were six. That is roughly three times the harmonic content, not the eighty per cent a real trumpet carries — the model will not reach that without overblowing, and a sine at the right pitch and a rich tone at the wrong one are both failures. bin/brass-regime-test.c asserts both properties together and exits non-zero on either, because this sits on a boundary that will not announce a regression. The change is surgical: re-measuring all 128 programs moves exactly 56-61 and leaves SynthBrass, the bowed strings, the reeds and the flute byte-identical. gm-timbre-space.json and the generated picker layout are regenerated from the new measurements, which lifts the brass from rows 13-14 to rows 11-13 — still dark, still honest, because the model still is not a trumpet. NOTE: fedac/native/src/gm_synth.c is the real file behind slab/menuband/Sources/CGMSynth/gm_synth.c, so this ships to AC Native OS as well as Menu Band. Landing it on main builds no OTA; that needs `ac-os oven`.