@maruaudio/dsp/physical/felt-hammer models a piano hammer's felt striking a string: unilateral power-law compression F = K · x^p and the hammer's momentum against a passive impedance load. Each sample runs four substeps, each solving the implicit compression by sixteen monotone bisections, and returns the force impulse delivered that sample. The force is never clipped; contact releases when the felt would go into tension. A caller may pass an incoming string-wave velocity and allow the hammer to recontact before it escapes, and an optional derivative-of-power term models felt loss. Long-memory hysteresis is not modelled.
Parameters
strikeFeltHammerRealtime(state, rate, velocity, mass, impedance, hardness, durationMs, exponent, lossMs):
| Argument | Clamp as coded | createFeltHammer value |
|---|---|---|
mass | At least 0.0005 kg | 0.008 kg |
impedance | At least 0.1 | 8 |
exponent | 1 to 3.5 | 2.5 |
lossMs | 0 to 2 ms | 0 |
durationMs, hardness | Contact time max(0.1 ms, duration) · (1.5 − hardness) sets the stiffness at 0.5 mm compression | stiffness 1e9 |
velocity | Hammer speed is 4 · velocity; the contact is active only when velocity > 0 | none |
strikeFeltHammer is the same call with lossMs defaulting to 0.
Lifecycle
createFeltHammer allocates one caller-owned state → strike at a note-on → feltHammerTickRealtime(state, incidentVelocity, allowRecontact) once per sample until active is false → resetFeltHammer puts the contact to sleep. feltHammerTick defaults the incoming velocity to 0 and recontact to off. Ticks allocate nothing and do no I/O.
When to use it
The excitation of a physical piano string: the stiff-string piano voice and its waveguide consume the impulse, so velocity changes the contact duration as well as the force.
Limits
- A contact sleeps when its energy falls below 1e-12 of the strike energy, a numerical threshold rather than a timer.
- The default load is a reduced instantaneous impedance; returning waves come only from the caller.