-
Notifications
You must be signed in to change notification settings - Fork 0
Statistics and Diagnostics
Stats is a tab in the app window — always present, between Peers and Settings (a fourth tab, Sharing, joins them in Share mode). It is where the numbers live: what the latency is made of, which links have fallen back, what every peer's transport targets are, and a live card per stream.
Nothing on this tab changes how audio behaves. The only things you can press are the grouping control, the collapsible per-peer headers, and the peer names in the Transport card, which are links to that peer's detail page.
Both of them turn an apparent gap into a piece of information, and neither is guessable.
A counter that is zero is not drawn at all. Several tags render only once their value rises above zero: half-frame fixes, format drops, and the unexpected-frame-type tag on a fallback link. So a card with fewer rows than this page describes is a healthy link, not a missing feature. An absent tag means this did not happen, not this is not measured.
"Unknown" and "direct" are different readings, and never render the same way.
Where the service does not report something, the app says so in as many words
rather than showing a plausible default. A session whose path is not reported
reads Path —, and its tooltip states outright: "This does not mean the
connection is direct; upgrade both ends to the same version." Treat a dash as
missing evidence, never as good news.
| Tile | What it is |
|---|---|
| Uptime | How long the audio service has been running — not the window. It advances every second locally between the service's own status reports, so it keeps ticking while the app is idle |
| IPC latency | The round trip of the last status request between this window and the local service on this machine. It is not the network time to a peer — that reading lives on the peer card |
| Sessions | How many streams are active right now, across all peers |
A restarted service resets Uptime to zero. That is the quickest way to confirm that a restart actually happened.
One row per active stream: the peer's name and what the stream is (Peer microphone, Local speakers, and so on), a horizontal bar, and the total on the right.
The bar is stacked in the order audio travels, and coloured by the four segments the stage list groups into: Network, Capture, Buffer, Playback. Each slice is sized in proportion to its milliseconds, so the widest block is where the time is going. The stage names and what each one is are in Latency.
Three things about it are worth knowing before you draw conclusions from a bar:
Only one of the three output tails is drawn. The playback queue, the bridged virtual sound card's queue and the virtual microphone buffer all receive the same decoded frame at the same time — they are parallel destinations, not sequential stages. Only the largest of the three is counted, on both machines, by the same rule. Drawing all three would make the slices add up to more than the total printed beside them.
A flat, uncoloured bar means no stage has a reading yet, not a stream with zero latency. The app deliberately draws no proportions rather than inventing a plausible split.
A total prefixed with ≥ is a lower bound. At least one stage that is known
to exist could not be read, or is known to be under-reported by the platform, and
it was not filled in with zero. Hovering the total says which case applies —
including "This reading only covers the local side", which means the peer has
not reported its half at all and the real end-to-end figure is higher by an
unbounded amount. The full rule, and the table of which device types make the
prefix permanent, is in Latency.
The footnote under the card — "System path only · Excludes Bluetooth/HDMI buffering" — applies to every row.
The whole card is hidden while nothing is streaming, because the empty state at the bottom of the tab already says the same thing once.
This card does not disappear when there are no sessions, and that is deliberate: a link can be backed up and dropping frames with no stream on it, and that is precisely the moment worth seeing.
It has three states, and they are not interchangeable:
| What it says | What it means |
|---|---|
| One or more rows | These peers are on TCP relay or Single-link mux right now |
| No fallback connections · Confirmed | The service looked and there are none. This is a conclusion |
| This service does not report fallback connections. | The service is too old to answer. This is not a conclusion — do not read it as "all direct" |
Each row starts with the peer's name, the path it is on, whether the link is up, and the link's address. Then two headline numbers, then a footer of counters.
These two exist nowhere else in the product, and between them they explain why a degraded link sounds the way it does.
| Reading | Non-zero / rising means | What to do |
|---|---|---|
| Send backlog | How long frames are waiting in the send queue, in milliseconds, not queue depth. A rising value means TCP is blocking the writer, and it is the most direct cause of stuttering | Fix the path — see Getting back to Direct (UDP). Nothing on this tab tunes it |
| Timed-out drops | Frames that exceeded the 440 ms budget before they could be sent were discarded on purpose. This is not a new source of loss: it leaves a hole the receiver's jitter buffer conceals correctly, instead of delivering stale audio | While this is still growing, AUTO refuses to raise the quality rung. Expect quality to stay down until it stops |
If both are zero and the peer is still under-running, the problem is not on this link's sending side. Look at the receiving machine.
Depth is reported as a wait in milliseconds rather than a queue length because the queue holds wire packets shared by every stream to that peer, and a packet is 10 ms of audio on the shallow rungs and 5 ms on the deep ones. Multiplying depth by a frame size would be wrong by the live stream count and by a factor of two, both of which move at runtime.
| Counter | Reading it |
|---|---|
| Backlog peak | The high-water mark of the same wait. A peak far above the current value means the stall has already happened and recovered |
| Last AUTO decision used | The backlog figure AUTO actually steered on in the last second. Reported separately from the instantaneous reading because only this one explains a rung change |
| Queue n / cap | Current occupancy against capacity |
| Queue drops | The writer stalled long enough to fill the queue completely. Distinct from timed-out drops, which are a deliberate gate rather than an overflow |
| TX / RX | Frames written to and read from this link |
| Unexpected frame type | Shown only when above zero, in red. A frame arrived whose kind does not belong on this transport — normally the two ends are running different versions |
Everything about why a degraded path behaves this way — the deeper buffer, the 440 ms gate, what AUTO watches instead of packet loss — is on Transport Tiers.
One gap is stated on the peer's detail page rather than hidden: this version of the service does not report why or when a link was downgraded. The counters above are all the evidence there is.
A read-only table: one block per peer, one row per direction, showing that direction's latency and quality targets.
This is the only screen in the app that shows every peer's four targets at once. The detail page shows one peer at a time, which is exactly how a machine can sit on a target nobody remembers setting without anything ever looking wrong.
- The peer's name is a link to that peer's detail page, where the values can be changed.
- In Mode A or Mode B, only the directions the peer actually has are listed — a peer with no default microphone has no Receive row.
- In Share mode both rows are always listed: this machine executes what the peer using it asked for, and whether this machine has the corresponding endpoint is a separate question.
- A cell reads
—when the service did not report a value. It is never back-filled with AUTO. - With no peers paired, the card says "Pair a peer to set its transport profiles." If peers are paired but none of them has any audio capability at all, the card is not rendered.
The two column headers carry ? buttons to
Latency and
Audio Quality.
Below the toolbar, one card per stream. The toolbar's segmented control groups
them by Peer (the default, with a collapsible header per peer showing
Streams n) or by Session (a flat list in the service's own order).
The service pushes a fresh set of numbers once per second, and each card's sparklines hold the last 60 points — one minute. That history is in memory only: reloading the window empties every sparkline while the numbers themselves carry on.
| Element | What it tells you |
|---|---|
#12 |
The service's internal stream number. Peers are what you recognise; this is for matching a card against a log line |
| Flow tag | Peer microphone, Local microphone, Peer speakers, Local speakers |
| Direction | Send or Receive, from this machine's point of view |
| Path tag | Only when degraded. A direct stream carries no badge — marking every healthy stream "fine" only trains you to ignore the one place that has to be noticed |
| Virtual / Peer-started | Virtual means an app selected this peer's virtual device and the system created the stream; Peer-started means the other machine opened it |
| Device name | Which virtual device triggered it — the only way to match a card here against the device you just picked in the system |
| Meta | The peer, the live wire format, and the channel count |
The wire format is written with both dimensions — Stream 48000 Hz · 24 bit —
because a sample rate alone spans three rungs of the ladder with double the
bitrate between them. When the bit depth cannot be read it drops back to the rate
alone rather than assuming 16 bit; when neither can be read it says
Stream rate — rather than showing 0 Hz.
The channel count is always 1 ch. Every AudioHub stream is mono, in every
mode. Nothing on this tab will ever read otherwise.
Each has a value and a one-minute sparkline. A — is a missing reading and never
a zero; a sparkline simply skips the seconds where a reading was missing rather
than plotting a nought.
| Metric | Reading it |
|---|---|
| Latency | The end-to-end total for this stream, with ≥ under the same rule as the waterfall |
| Continuity | 100 minus the weighted concealment rate: the share of output duration filled with something other than the peer's original audio. On a send-only stream this machine has no measuring point, so the figure comes from the peer — the tooltip says so |
| Packet loss | Loss at the socket. It does not track continuity: 2 % loss can be inaudible when concealment absorbs it, and 0 % loss can still sound wrecked |
| Jitter | Frame-to-frame arrival spread |
| Bitrate | A sliding window. — while the window is too short — not zero |
| Quality | The rung: 0 is best (48 kHz · 32-bit float) and the number rises as quality falls. Rung 2 is the best rung AUTO will select on a direct path. The tooltip also names this stream's measured rate and depth, so you can see AUTO having moved. See Audio Quality |
Present only on streams that synchronise volume. It is a read-out, not a control — the control is on the peer card.
It is labelled Local volume on a receiving stream and Peer volume on a sending one, and carries a Fixed tag when the device at the far end exposes no volume that can be driven. See Volume.
| Counter | Reading it |
|---|---|
| RX / Lost / TX | Packets received, lost, and sent for this stream |
| Buffer | The jitter buffer's current depth, given in both milliseconds and frames, because the latency setting is in milliseconds and the depth used to be readable only in frames |
| Rung changes | How often AUTO has moved this stream. A number that keeps climbing is a link AUTO cannot settle on |
| Path | Which connection method this stream's bytes are on. Path — means unreported, not direct |
Both are hidden while zero, both are bad news when present, and both name a specific fix.
| Tag | What it means | What to do |
|---|---|---|
| Half-frame fixes (amber) | On the deep rungs a frame is split across two 5 ms packets. This counts frames where only one half arrived, and the stream was delivered with the missing half concealed. It is invisible to every other counter: the jitter buffer sees a full-length frame and records neither a loss nor an under-run | If it keeps rising, packets are being lost. Drop the quality profile by one step. See Audio Quality |
| Format drops (red) | The peer's declared wire format did not match the number of bytes it sent, so those packets were discarded. In the ear this is periodic holes of silence | Any non-zero value means the two ends are on different versions. Upgrade both to the same one |
Two more tags can appear, and neither occurs in normal use: a Pass / Fail tone check and a Mix checks count. Both require a stream opened by the command line with a verification frequency, which the interface never does. If you have not run a probe, you will not see them.
With no active streams the tab still shows the tiles, the Fallbacks card and the Transport card, plus an empty state whose wording depends on the mode:
- Mode B: "Select a peer AudioHub device in Sound settings or an app to see live metrics." Mode B has no per-peer switches, so pointing at them would be wrong.
- Anything else: "Start a stream from a peer card to see live metrics."
-
Troubleshooting
— why an absent row and a
≥total are both normal. - Transport Tiers — what the Fallbacks counters are measuring.
- Latency — the stages behind the waterfall.
- The peer details page — where the Transport card's values are actually set.
Start here
Using AudioHub
- Window and tray
- Operating Modes
- Virtual Driver
- Discovery and Pairing
- Peer detail page
- Share Protocols (Sharing tab)
- Web Access
How it behaves
Reference
- Settings Reference
- Platform Notes
- Firewall and network
- CLI Reference
- Versions and Compatibility
- Glossary
- Licenses and Attribution
Troubleshooting and removal
This wiki describes AudioHub 1.0.0.