feat(audio): account for source directivity in diffuse reverb calculations

Previously, diffuse field reverberant gain and critical distance calculations
assumed an omnidirectional sound source (Q = 1), regardless of cone settings.
Directional sources concentrate sound energy in specific directions, reducing
the total acoustic power injected into the room and lowering the reverberant
field level relative to the direct sound on-axis.

Incorporate source directivity factor Q into the acoustics model:
- Compute closed-form directivity factor Q in src/physics/cone.ts by
  integrating squared cone gain over the unit sphere.
- Scale reverberant field gain by 1 / sqrt(Q) (-10·log10(Q) dB) and adjust
  critical distance by sqrt(Q) in src/audio/reverb.ts.
- Update AudioEngine and signal path UI to present directivity index (DI)
  and adjust room dominance evaluations.
- Add unit tests verifying Q against brute-force numerical quadrature and
  confirming critical distance behavior.

Test Plan:
- `npm run typecheck` -- passed clean
- `npm test` -- 125/125 tests passed (6 test suites)
- `git diff --cached --check` -- no whitespace errors
This commit is contained in:
2026-07-26 18:51:27 +02:00
parent 1a827b8b0d
commit 95d5125d3c
8 changed files with 245 additions and 16 deletions
+11 -1
View File
@@ -40,11 +40,21 @@ locally in the page.
The one idea the app is built around. The direct sound falls as `1/r`; the
reverberant field does not fall at all. They cross at the **critical distance**,
`rc = √(R / 16π)`, drawn as a ring on the floor:
`rc = √(R / 16π)`, drawn as a ring on the floor:
- **Inside the ring** the source dominates. You can point at it with your eyes shut.
- **Outside it** the room dominates. It does not get quieter as you back away — and that constancy is a large part of how your ears judge distance.
`Q` is the source's directivity factor — how much more intensity it puts on its
axis than an omnidirectional source of the same total power. It belongs in that
formula because the reverberant field is fed by *radiated power*, while the ring
is measured against the *on-axis* direct sound. A cone that throws its energy
forward excites the room far less than its on-axis level suggests: the default
70°/160° cone has `Q = 5.07`, a directivity index of 7.1 dB, which pushes the
ring from 6.1 m out to 13.7 m. Drop `Q` and reflections stay conspicuously loud
when you walk behind the speaker — the room is being driven as if the speaker
radiated backwards as hard as it radiates forwards.
Press <kbd>3</kbd> for a guided walk through it.
## Controls