soundstage_extender
NODEExtends the stereo image from where the mix put it. Wide sounds go further out and the ones at the edges go past the speakers, while center sounds and the ambience stay where they are.
Parameters
{
"amount": 1,
"outside_deg": 45,
"speaker_angle_deg": 30,
"type": "soundstage_extender"
}How it is computed
per STFT bin (the window is 1024 samples at 48 kHz in length, hop 1/4):
1. smooth the L/R covariance over about 30 ms
2. u = its principal eigenvector = [cos ψ, sin ψ · e^(jφ)]
c = (λ1 - λ2) / (λ1 + λ2) how much the bin is one direct sound
3. p = uᴴ x (direct) a = x - u · p (ambience)
4. the pan position from ψ is extended by amount,
and pushed out by outside_deg from push_from to the edge;
it moves in proportion to c
5. inside the speakers: p is re-panned at the new angle
outside: feeds = (Hᴴ H + β I)⁻¹ Hᴴ · d(θ)
H = speakers to ears, d = ears for a source at θ (spherical head)
6. out = re-placed p + aUsing it
It only moves what is already wide.
Center sounds and the ambience are left alone. A sound panned halfway goes further out and a sound at the edge goes past the speaker, so the left to right order of the mix stays the same.
The outside image needs the sweet spot.
It is computed for a head centered between the speakers at speaker_angle_deg. A few centimeters off still works; about 10 cm off and the image falls back inside the speakers. It does nothing useful on headphones.
It adds one window of delay.
About 21 ms, or 23 ms for material in the 44.1 kHz family. Adding or removing the node while playing leaves a gap of that length. Changing its values does not.
Sounds that overlap move less.
When two sounds share a frequency at the same moment, the bin points between them and neither reaches its target. The error is always on the short side: nothing is pushed further than asked.
Do not combine it with crosstalk_canceller.
Both cancel crosstalk. Used together, the cancellation is applied twice.