perf: remove per-sample waste from the compressor/limiter hot path

Found by reading the audio-thread code, not by profiling - no profiler is
set up in this project yet. All four are algorithmic or arithmetic wins,
none change the DSP result; the existing tests still pass.

- oversampler: max_true_peak recomputed its circular-history tap index
  (including a % TAPS_PER_PHASE) inside the phase x channel loop, though
  the index depends only on pos/k - 8x redundant. Hoisted to a per-sample
  precomputed index array. This runs unconditionally every sample (it
  feeds the limiter's true-peak detector, not gated by metering), so it
  was the highest-value fix.

- limiter: the sliding-window max rescanned the entire look-ahead ring
  (~73 samples at 48kHz/1.5ms) every sample - O(window) per sample.
  Replaced with an O(1)-amortized monotonic-deque sliding max, backed by
  preallocated ring arrays and RT-safe. Covered by a new test against a
  naive brute-force reference. Also precomputed the constant true-peak
  margin gain in prepare() instead of a powf every sample.

- compressor: replaced per-sample log10/powf(10, x/20) with the
  equivalent ln/exp forms, mirroring nih-plug's own gain_to_db_fast /
  db_to_gain_fast. Called 4x/sample (3 bands + 'All').

- both: replaced % capacity ring-index math (a real integer division,
  since capacity is not a power of two) with a conditional-subtract
  wrap_add helper. Left the oversampler's % TAPS_PER_PHASE alone - that
  divisor is a compile-time constant LLVM already turns into a multiply.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LU1NRL7fAaZTtFMTTPn2b1
This commit is contained in:
Mikkeli Matlock
2026-08-31 21:19:23 +09:00
parent eda3d09399
commit 03d60a157b
4 changed files with 165 additions and 25 deletions
+4 -2
View File
@@ -241,7 +241,9 @@ impl Plugin for Codename206 {
// Drive + compress each band (per-sample smoothed pre-gain & makeup), then sum.
summed[..n].fill(0.0);
for b in 0..3 {
let pre = util::db_to_gain(band_params[b].pre_gain_db.smoothed.next());
// `_fast` skips the below-(-100dB) branch, which pre_gain_db's -24..+36 range
// never reaches, in exchange for a cheaper exp() instead of a general powf().
let pre = util::db_to_gain_fast(band_params[b].pre_gain_db.smoothed.next());
for ch in 0..n {
band_in[b][ch] *= pre;
}
@@ -272,7 +274,7 @@ impl Plugin for Codename206 {
}
// 'All' aggregate channel over the summed bands (driven before its compressor).
let all_pre = util::db_to_gain(self.params.all.pre_gain_db.smoothed.next());
let all_pre = util::db_to_gain_fast(self.params.all.pre_gain_db.smoothed.next());
for ch in 0..n {
summed[ch] *= all_pre;
}