Commit Graph

5 Commits

Author SHA1 Message Date
Geoffrey McRae
87aa61510c [client] audio: harden low-latency streaming
Rework audio provider and backend lifecycles so playback and capture
callbacks quiesce without blocking real-time threads. Move activation,
teardown, controls, retries, and diagnostics onto bounded workers.

Harden USB audio cadence, feedback, and capture recovery.
Preserve source clocks through recording and pace packets from the
device clock. Bound queues, waits, conversion buffers, and packet sizes.

Make PipeWire and PulseAudio stream control thread-safe and recoverable.
Correct latency clock domains, coalesce rate updates, preserve recent
capture under overload, and keep logging outside real-time callbacks.
2026-08-10 16:36:12 +10:00
Geoffrey McRae
4434985aa3 [client] usb audio: add microphone recording
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
Add a composite UAC2 microphone function with its own clock so
recording and playback can use independent sample rates.

Packetize asynchronous capture through usbredir, follow the host
capture clock, and preserve the newest frames across stalls.

Reconfigure active recording without another permission prompt and
fix lost PipeWire capture wakeups.
2026-08-10 06:32:05 +10:00
Geoffrey McRae
0f3c1db261 [client] usb audio: add asynchronous clock feedback
Advertise an asynchronous UAC2 OUT endpoint with explicit feedback so
Windows paces USB audio from the host playback clock.

Drive feedback from measured backend consumption plus the existing
buffer phase controller. Preserve the local and backend resampler paths
for providers without active feedback.

Keep audio diagnostics in the correct clock domains, report ring and
backend latency separately, and avoid hot-path feedback wakeups.
2026-08-10 04:44:55 +10:00
Geoffrey McRae
ff665c2031 [client] usb audio: support up to 192khz 24-bit
We can not support 32-bit because Windows is buggy:

The exact Windows 11 mmsys.cpl from build 26100.8737 populates Speaker
Setup testing against hard-coded speaker masks and for each calls
IKsFormatSupport::IsFormatSupported() using 24 hard-coded PCM formats.

These formats do not include 32-bit in 32-bit, consequently, every one
of the wizard’s format probes fails and it inserts zero channel-list
entries.

It does however test for 24-bit in 32-bit which passes, however this
exposes another breakage due to an inconsistency inside Windows
usbaudio2.sys

For bSubslotSize = 4, bBitResolution = 24, Windows does this:

1. It publishes a KS range whose minimum and maximum bit depths are both
   taken from bBitResolution, so the range says 24-bit.
2. It correctly constructs the actual stream format as:
   wBitsPerSample = 32, wValidBitsPerSample = 24
3. KS range intersection rejects that 24-in-32 format because its
   container is 32 bits while the published range says 24.
4. A packed 24-bit candidate passes range intersection, but the
   subsequent exact stream check rejects it because it uses a three-byte
   container while USB advertises four bytes.

Therefore no format can pass both checks. That exactly explains:

* USB Device Tree Viewer seeing 24-bit device ranges.
* The MMDevice endpoint exposing no usable formats.
* Windows being unable to start playback.

I verified this in the exact Windows 10.0.26100.8737 driver:

* KSPin::AddDataRange stores bBitResolution into both KS bit-depth
  bounds.
* MiniportWave::DataRangeIntersection tests those bounds.
* WaveFormatInfo::IsMatchingStreamFormat separately compares both the
  container width and valid-bit count.
2026-08-10 03:47:55 +10:00
Geoffrey McRae
6979b93da5 [client] usb audio: emulate UAC2 playback
Add a fixed-format USB Audio Class 2 playback device for the
client-side USB redirection bridge.

Advertise stereo 48 kHz IEEE float audio and handle enumeration,
configuration, alternate settings, clock requests, and isochronous data.
2026-08-09 21:30:20 +10:00