feat(audio): WASAPI exclusive-mode direct stream (Windows)
The render thread and the handle. COM objects are !Send, so one thread owns
every one of them for the life of the stream and this struct is a bounded
channel plus atomics - the same back-pressure snd_pcm_writei gives the ALSA
path for free.
Opens by ENDPOINT ID, never by friendly name: Windows gives several
endpoints the same name, which is what hid this DAC from the picker until
249adc77b. Walks the format ladder, pre-aligns the period to 128 bytes,
keeps the documented NOT_ALIGNED recovery for the devices that still need
it, joins MMCSS Pro Audio, and refuses S_FALSE loudly - a "closest match" is
by definition not the format we asked for.
Verified against the owner's Cambridge Audio USB Audio 2.0 with the new
example, and it matches the spike exactly:
rate 96000, S24In32 (24/32), period 30000 hns, buffer 288 frames,
realigned false, timing Events, mode DirectHardware,
960000 frames, 0 underruns, 0 event timeouts
Three faults were found on the way, and all three were in the MEASUREMENT
rather than the audio - worth recording because each looked like a hardware
problem:
- 339 "underruns" were event timeouts counted in the same counter. Split
them; they are different faults and were hiding each other.
- 337 event timeouts came from a 2x-period deadline. At a 3 ms period that
expired on 10% of wakeups because Windows scheduling is not that
punctual. The deadline exists to stop the thread hanging on a dead
device, not to detect glitches, and the spike waited 1000 ms and saw
none in ten minutes. It is generous now.
- The last 2 were a drain's trailing silence. A drain emitting silence is
the drain working.
The stub for every other platform mirrors alsa_direct's: constructors refuse,
teardown succeeds, so a caller written against this compiles and unwinds
everywhere. `cargo tree` shows exactly one windows v0.62.2 - no second
windows tree entered the graph.
cc
This commit is contained in:
4 files changed
+897
No files matched your search
@@ -64,3 +64,15 @@ jack = "0.13"
|
||||
# CoreAudio for device probing, sample rate switching, and (future) hog mode / exclusive mode
|
||||
coreaudio-rs = "0.14.1"
|
||||
objc2-core-audio = "0.3.2"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
# WASAPI exclusive mode (phase B). HEnquist's crate, the one CamillaDSP
|
||||
# uses. `windows` is pinned to the 0.62 line cpal already resolves, so
|
||||
# this adds no second windows tree to the graph.
|
||||
wasapi = "0.24"
|
||||
windows = { version = "0.62", features = [
|
||||
"Win32_Foundation",
|
||||
"Win32_Media_Audio",
|
||||
"Win32_System_Com",
|
||||
"Win32_System_Threading",
|
||||
] }
|
||||
Reference in new issue
Block a user