Commit Graph
3 Commits
Author SHA1 Message Date
Thore CimbalandClaude Opus 4.8 914eb59575 docs(adr): ADR-0018 — client-side noise suppression, opt-in and self-hosted
sorb's decision after the prototype: integrate DeepFilterNet3 as a LiveKit track
processor, off by default, assets fetched only when the user enables it, checkbox
plus slider, 35 percent default.

Opt-in is what makes the 23.3 MB affordable — only those who benefit pay for it.
Three of the source specification's assumptions did not survive measurement and are
recorded as rejected alternatives: the dry/wet mixer (the model limits attenuation
natively, and mixing raw signal back would return the keystrokes), the Rust/wasm
build (a maintained package makes it unnecessary), and loading assets from the
vendor CDN (every participant's IP to a third party at call start).

Mobile stays untested by choice; since the filter is opt-in it simply stays off on
weak devices, so that is a follow-up rather than a blocker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-15 12:00:00 +00:00
Thore CimbalandClaude Opus 4.8 9ff6e09b1d docs(issues): #0054 — prototype works, 35 percent suppression is enough
Built the throwaway prototype and sorb tested it: keyboard gone, voice natural,
at 35 percent rather than the 100 percent the spec assumed as default. That
settles the control question — the package exposes setSuppressionLevel and the
wasm carries atten_lim, so DeepFilterNet limits attenuation natively and the
spec's dry/wet mix drops out entirely, taking its missing delay node and phase
problem with it.

Measured what the spec had guessed: 23.27 MB per client, an order of magnitude
above RNNoise. Also found that the package fetches model and wasm from a
third-party CDN at call time, which a self-hosted platform cannot accept — the
asset URL is configurable and the prototype already serves them locally, so that
path is proven rather than assumed.

Still open and decision-relevant: CPU figures, the phone, and the standing cost of
carrying this through every upstream rebase.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-15 12:00:00 +00:00
Thore CimbalandClaude Opus 4.8 a328dacc50 docs: supersede ADR-0006, open #0054 on client-side AI noise suppression
ADR-0006 (Docusaurus as the shared reading surface) is superseded by ADR-0014,
which ADR-0014 had only recorded for ADR-0007. The schema has no 'deprecated', so
superseded with a pointer is the fitting lifecycle state, same shape as ADR-0007.

#0054 evaluates an external architecture spec for filtering keyboard noise with a
WebAssembly model in the client. It holds up on diagnosis, placement and the
awkward parts (128-vs-480 sample buffering, the Chromium worklet leak, SIMD), and
it does not contradict the fork's earlier rejection of ML denoising — that one was
about the server side, for a reason that does not apply here.

It does not hold up on: a missing delay node, which would make the dry/wet mix comb
filter audibly; the premise behind dry/wet at all, since DeepFilterNet can limit
attenuation natively and mixing raw signal back in returns the very keystrokes we
want gone; PESQ figures compared across different test sets; unmeasured bundle size;
throwaway npm packages; and no mention of the standing cost of carrying this through
every upstream rebase.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-15 12:00:00 +00:00