Skip to content

Drum whole-voice math validation

Status: Implemented and landed in Pulp PR #7869

Scope: TomVoice only; no kick, snare, hat, clap, cymbal, membrane, string, zap, FM6, or FM8 behavior changed

Canonical execution plan: Drum Whole-Voice Math Profiling and Bounded Optimization

Pulp chooses drum math alternatives from complete production-voice evidence, not from isolated transcendental benchmarks. The 2026-08-27 census measured 13 non-FM percussion scenarios at 44.1, 48, and 96 kHz with block sizes 32, 64, 128, and 512. Sine, exponential, and power families in kick, snare, cymbal, membrane, string, and zap voices could not plausibly produce a greater-than-10% whole-voice gain, so those voices remain on their reference paths.

The generic and SDS-V-family toms were the sole exception: their noise ladder's exact tanhf accounted for 37.30% and 34.00% of sampled whole-voice time. Selecting the existing FastMath::tanh implementation at that consumer produced the following complete-hit Release results across all 24 tom rate/block cells. Each cell reports the median paired gain from independent processes; each process itself uses 11 trials of three complete hits. Executable order was counterbalanced to limit temperature and frequency-order bias. The generic voice used three processes, while the narrower SDS-V-family margin was confirmed with five.

Voice Minimum gain Median gain Maximum gain
Generic tom 14.87% 16.84% 19.19%
SDS-V-family tom 10.14% 16.07% 17.41%

No declared configuration lost after cross-process median aggregation. The narrowest cell was the SDS-V-family voice at 96 kHz with 32-frame blocks, so that cell's margin is the reopen trigger if compiler, architecture, or voice lifetime behavior changes.

The 0.75-second acceptance corpus covered all eight tom presets, velocities 0.2/0.82/1.0, all three rates, and 32/512 block partitions. Across 144 cells, the worst candidate/reference changes were 0.0000393% peak, 0.00000343% RMS, 0.000246% for a transient/tail window, and 0.0000654% for the spectral-probe signature. Every render was finite and allocation-free; repeated renders and block partitions were bit-exact within each profile.

TomVoice::LadderMathProfile::reference remains the default. Select realtime_efficient only while the voice is idle; the setter rejects a change during an active hit so one hit never crosses saturation curves.

Enable the measured Tom profile

Include <pulp/signal/drum/tom.hpp> and link Pulp::signal. Select the profile during setup or between hits:

pulp::signal::drum::TomVoice tom;
tom.prepare(sample_rate);

const bool accepted = tom.set_ladder_math_profile(
    pulp::signal::drum::TomVoice::LadderMathProfile::realtime_efficient);

accepted is false if a hit is active. The selection applies to the noise ladder inside every TomVoice preset, including the generic and SDS-V-family presets. It does not alter other drum voice classes. Omit the setter, or select LadderMathProfile::reference, to retain reference math. Use ladder_math_profile() to inspect the current selection.

The earlier FM6 and FM8 conclusions are unchanged. FM6 remains a measured whole-voice performance NO-GO, and FM8 remains a quality NO-GO under its predeclared peak-change gate.