@maruaudio/dsp/physical/piano-scale gives a piano model each key's physical string data in SI units, and the tuning equations that go with it. configurePianoKeyScale interpolates speaking length, steel core diameter and effective wound linear mass geometrically between eight A-register anchors, then solves the tension that keeps the first partial at the requested frequency once bending stiffness is included, and derives the inharmonicity coefficient, string count, hammer mass and load impedance. The anchors are authored, provisional values, not measurements of an instrument.
| Function | Equation |
|---|---|
pianoFrequency(note, ref, tune, bass, treble) | ref · 2^(o + (tune + stretch · o³) / 1200), o = (note − 69) / 12; bass stretch below A4, treble above |
pianoModeFrequency(f0, n, B) | f0 · n · √((1 + B n²) / (1 + B)) |
pianoHammerContactDuration(ms, f, mass, bass, treble) | ms · (440 / f)^tracking · √(mass / 0.008) |
pianoRegisterCurve(note, values) | Linear between eight A-register values, clamped to notes 21 to 105 |
Lifecycle
createPianoKeyScale allocates one caller-owned profile → configurePianoKeyScale(profile, note, frequency, lengthRatio) at each note event, allocation-free. The other functions are pure. The register-curve variants (pianoFrequencyWithRegisterCurve, pianoStiffnessWithRegisterCurve) add a per-register tuning or stiffness curve when enabled and return the plain result otherwise.
When to use it
Feeding a stiff-string or modal piano voice per-key tension, impedance and inharmonicity that stay tuned across the keyboard, and stretched tuning in cents per octave cubed.
Limits
- Notes are clamped to 21 to 108 (A0 to C8) for the scale; one string below note 29, two below 41, three from there up.
- Tension is at least 1 N. Hammer mass falls geometrically from 12 g at A0 to 3 g at C8. Bending uses the steel core only (Young's modulus 2e11 Pa); the winding adds mass, not stiffness.
- Contact-duration tracking uses the bass exponent below 440 Hz and the treble exponent above.