Audio devices
Audio is where this product is most useful and least finished. Device control works and is reversible. Loopback capture runs but is silent without a permission grant. The virtual microphone is written and blocked on a certificate.
List devices
Section titled “List devices”device-bridge audio list [--json]Each entry carries id, name, isInput, isOutput, isDefaultIn,
isDefaultOut. A single physical device can expose both an input and an output
stream, so isInput and isOutput are not mutually exclusive.
device-bridge audio list --jsonSwitch the default, then put it back
Section titled “Switch the default, then put it back”device-bridge audio default-in <name|id>device-bridge audio default-out <name|id>This is the trick that makes auto-testing work without clicking through an app’s settings: set the system default and the app under test picks it up on its own.
Spike S7 proved it end to end — enumerated every device, switched the default
input from the built-in microphone to a USB device, verified by read-back, and
reverted. Both --name and numeric id resolve; an unmatched argument is an error,
never a silent no-op.
macOS has no default camera
Section titled “macOS has no default camera”There is no system-wide default camera on macOS — every app chooses its own. This is an API that does not exist, not a feature that is missing. Recorded in ADR 0010 so nobody goes looking for it again.
Speaker loopback (audio-out)
Section titled “Speaker loopback (audio-out)”device-bridge start audio-out --port 9332 --token "$WINDOWCTL_TOKEN"Captures what the machine is playing, using the Core Audio process tap API
(macOS 14.4+) — no third-party device installed, no default-device switching. Each
frame is a 16-byte header with Kind = 2 (speaker) and
Format = 2 (interleaved float32, little-endian) followed by raw PCM.
Virtual microphone (audio-in)
Section titled “Virtual microphone (audio-in)”This is the lane that feeds audio into the app under test, and it is the reason
the product exists. The implementation is a CoreAudio AudioServerPlugIn — a
user-space HAL plugin loaded by coreaudiod, no kernel extension — written from
Apple’s permissive NullAudio sample rather than forked from a GPL project.
State today:
- The driver is code-complete, bundle id
com.deemwar.windowctl.audio. - It is signed with a hardened runtime and a secure timestamp.
- A notarization script (
notarytool submit --wait+stapler staple) is ready. coreaudiodwill not load it. It rejects signatures that are not Developer ID:spctl -a -t installrejects both the Apple Development and the Apple Distribution signature. The unblock is a Developer ID Application certificate plus notarization.
device-bridge install audio # copies to /Library/Audio/Plug-Ins/HAL, restarts coreaudioddevice-bridge uninstall audioinstall audio needs sudo and restarts coreaudiod; it is an explicit verb
precisely because it is a privileged, system-wide change. Until the certificate
lands, the device will not appear in audio list.
Windows
Section titled “Windows”Windows has no user-mode virtual-microphone API at all. A true virtual mic there needs a kernel-mode AVStream driver, an EV code-signing certificate and Microsoft attestation signing — weeks of work plus ongoing overhead, wildly out of proportion for a test tool. ADR 0009 defers it indefinitely in favour of a user-mode audio router, and will only be revisited when a named target both rejects a router-backed mic and is important enough to justify the cost. None of the Windows audio path is implemented yet regardless.