re: the buffer/dropout relationship is not monotonic, and a gap-rate bar misses it

Extends the latency finding with a third point, and it changes the advice.

  xenia default (~5.3 ms)   347.5 s   39.3 percent silence   30.5 gaps/s   3.94 ms median
  PULSE_LATENCY_MSEC=200     88.0 s   15.6 percent silence    3.5 gaps/s  37.33 ms median
  PULSE_LATENCY_MSEC=500     87.9 s   50.1 percent silence    1.3 gaps/s 346.67 ms median

200 ms is 2.5x better than the default; 500 ms is worse than either. Raising the
buffer keeps cutting the gap RATE while total silence bottoms out at 200 ms and
then doubles, because an over-large buffer starves in a few enormous holes rather
than many small ones.

That is also a warning about the metric. The port s check-capture bar is 20
gaps/s, derived from sound controls -- starved 32.9, genuine music bed 3.3, voice
track 0.03. The 500 ms file scores 1.3 gaps/s, better than a real music bed,
while being 50 percent silence: a gap-rate test alone would pass the worst
capture of the three. It needs a total-silence companion. Same shape as the
defect that made a per-channel level table useless -- one number that cannot see
the failure mode next door.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
This commit is contained in:
sylph-decoder
2026-08-29 16:35:46 +00:00
parent b56d0e1fb6
commit e8afbc8632

View File

@@ -212,16 +212,25 @@ is stock with no fragment tuning at all.
`PULSE_LATENCY_MSEC` overrides what SDL's PulseAudio backend requests. Measured,
same title, same sink, same `parec` invocation:
| client buffer | duration | silence | **gaps/s** | median gap |
| client buffer | duration | **silence** | gaps/s | median gap |
|---|---|---|---|---|
| xenia default (~5.3 ms) | 347.5 s | 39.3 % | **30.5** | 3.94 ms |
| `PULSE_LATENCY_MSEC=200` (114.7 ms reported) | 88.0 s | 15.6 % | **3.5** | 37.33 ms |
| xenia default (~5.3 ms) | 347.5 s | 39.3 % | 30.5 | 3.94 ms |
| **`PULSE_LATENCY_MSEC=200`** (114.7 ms reported) | 88.0 s | **15.6 %** | 3.5 | 37.33 ms |
| `PULSE_LATENCY_MSEC=500` | 87.9 s | **50.1 %** | **1.3** | 346.67 ms |
**An 8.7× reduction in gap rate from one environment variable.** For scale, the
port's controls put a *starved* file at 32.9 gaps/s, a **genuine music bed at
3.3**, and a voice track that is 53 % pauses at 0.03, with their bar at 20 —
so the default lands squarely in "starved" and 200 ms lands at the level of real
content.
**200 ms is 2.5× better than the default. 500 ms is worse than either.** The
relationship is **not monotonic**: raising the buffer keeps cutting the gap
*rate* (30.5 → 3.5 → 1.3) while the *total silence* bottoms out at 200 ms and
then doubles, because an over-large buffer starves in a few enormous holes
instead of many small ones — a 346 ms median gap at 500 ms against 37 ms at 200.
🔴 **And that is a warning about the metric, not just the setting.** The port's
`check-capture` bar is **20 gaps/s**, derived from good controls (starved 32.9,
genuine music bed 3.3, voice track 0.03). The 500 ms file scores **1.3 gaps/s —
better than a real music bed — while being 50 % silence.** A gap-*rate* test
alone would pass the worst capture of the three. It needs a **total-silence**
companion, and this is the same shape as the defect that made a level table
useless: one number that cannot see the failure mode next door.
⚠️ **Not yet a clean bill of health.** The two runs are not like-for-like: 88 s
against 347 s, and the short one covers the splash logos, where silence between