-
Notifications
You must be signed in to change notification settings - Fork 0
Audio Quality
The wire format is chosen from a six-rung ladder. One rung fixes two parameters at once: sample rate and bit depth.
Rung 0 is the best. The number increases as quality decreases, which matches the direction AUTO moves when a link degrades.
| Rung | Format | Audio bitrate | Wire packetisation | Setting id |
|---|---|---|---|---|
| 0 | 48 kHz · 32-bit float | 1536 kbps | 2 × 5 ms | pcm48k32f |
| 1 | 48 kHz · 24-bit | 1152 kbps | 2 × 5 ms | pcm48k24 |
| 2 | 48 kHz · 16-bit | 768 kbps | 1 × 10 ms | pcm48k16 |
| 3 | 32 kHz · 16-bit | 512 kbps | 1 × 10 ms | pcm32k16 |
| 4 | 24 kHz · 16-bit | 384 kbps | 1 × 10 ms | pcm24k16 |
| 5 | 16 kHz · 16-bit | 256 kbps | 1 × 10 ms | pcm16k16 |
Three Opus rungs (64 / 128 / 256 kbps) are drawn on the slider but cannot be selected: this build does not link libopus. They are shown rather than hidden so that "why does my machine not have that option" has a visible answer.
Bitrate is audio payload only — rate × depth ÷ 1000, excluding protocol
overhead. Deep rungs carry proportionally more overhead because they send two
packets per 10 ms rather than one, so do not reverse-engineer measured bandwidth
from this column.
No rung causes IP fragmentation. The largest datagram any rung produces is 1044 bytes, which stays comfortable even against a 1420-byte tunnel MTU.
The two get confused constantly, so the UI states both.
Usable audio bandwidth is half the sample rate (the Nyquist limit). A 48 kHz wire rate carries content up to 24 kHz. Both numbers are correct and they differ by a factor of two — a card showing "48 kHz" and a detail panel showing "24 kHz" are agreeing with each other, not contradicting.
Also easy to misread: 16 kHz is a sample rate; 16 bit is a bit depth.
Every rung label writes both dimensions in full for exactly this reason.
Bit depth does not affect bandwidth. It sets the quantisation precision of each sample, which shows up as noise floor, not as frequency range. 16-bit is CD precision, 24-bit is the standard interchange depth between professional audio devices, and 32-bit float is the pipeline's own internal format — at that rung the wire stage performs no quantisation at all, because the codec degenerates to a byte-order copy.
Rungs ascend by bitrate, which means sample rate is bought up to 48 kHz first, and only then is bit depth bought.
Low rate combined with high depth never appears on the ladder, because it is never a good trade. 48 kHz is the only rate that avoids resampling entirely, and this pipeline's resampler is linear interpolation without an anti-aliasing low-pass. Giving up 48 kHz to gain bit depth trades roughly 90 dB of damage for 48 dB of improvement.
Read downward, the ladder therefore sheds bit depth first (inaudible) and only then sheds bandwidth (audible). That behaviour is not a second rule set; it falls out of the ordering.
Only two values on the bit-depth axis are industrially meaningful — 24-bit as the standard interchange depth, and 32-bit float as the native pipeline format — which is why one sample rate occupies three consecutive rungs.
AUTO moves one rung at a time based on packet loss and jitter reported back by the receiver.
| Direction | Condition |
|---|---|
| Down one rung | loss > 5 % or jitter > 15 ms — acts immediately |
| Up one rung | 10 consecutive clean periods, where clean means loss < 0.5 % and jitter < 5 ms |
The statistics period is one second, so recovery takes about ten seconds at minimum.
The asymmetry is the hysteresis. A single bad period drops a rung immediately; a rise requires an unbroken run. Any period that is neither clean nor bad resets the streak to zero rather than counting toward it.
AUTO will not go above rung 2 (48 kHz · 16-bit).
It starts there and never climbs past it. The reason is bandwidth courtesy: rung 1 costs 50 % more bandwidth than rung 2 and rung 0 costs 100 % more, for a difference that is not audible. Doubling every AUTO user's bandwidth without being asked is not a reasonable default.
So AUTO is best understood as a "don't waste bandwidth" control. The deep rungs are there for when you explicitly want them.
On degraded links the ceiling drops further, to rung 3 — see Transport Tiers.
The two deep rungs cannot fit a whole 10 ms frame's payload into one Ethernet datagram, so they are split into two 5 ms packets on the wire. The frame length itself does not change.
The receiver pairs the halves by sequence number. If the partner packet has not arrived, it delivers a half-frame concealment rather than waiting — waiting would convert a bandwidth problem into a latency problem.
The diagnostics page counts these. A few are inaudible. Continuous growth means the link is losing packets, and dropping one rung resolves it, since rung 2 and below send a single packet per frame and cannot be half-lost.
Quality is set per peer, per direction, on that peer's detail page. There is no global slider.
Latency is executed by the receiving end and quality by the sending end, so the two settings on one row physically take effect on two different machines. This affects only which side's reading moves first; you still set both from here, and the peer complies.
The settings page keeps a read-only overview of every peer's four settings — the only place where "which peer is still on AUTO" is visible at a glance.
Using it
How it behaves
Settings
Reference