* feat(audio): add PipeWire capture path with system-audio sources
Enumerate PipeWire sinks via pw-dump and expose their monitors as
"System audio: <name>" capture devices at negative device indices
(-2..), alongside the existing PortAudio microphones. Recording,
device test, and stream-reconnection paths route to a
pw-record-backed stream shaped like a PyAudio stream, so the VAD and
silence-detection loop is unchanged.
Playback ducking is skipped when the selected source is a monitor,
since ducking the default sink would also duck the captured audio.
Closes#751
* test(audio): restore stashed numpy instead of re-importing it
test_audio_input imports numpy lazily; deleting the MagicMock that
earlier test modules leave in sys.modules re-imported a second numpy
module object whose lazy submodule attributes (linalg, testing) were
unpopulated while sys.modules kept the first object's entries. The
next test file to reach for numpy.testing hit a __getattr__ import
loop (RecursionError in TestDownmixToMono on CI).
Restore the conftest-stashed _vocalinux_real_numpy instead, matching
the pattern tests/test_recognition_manager_device_config.py already
uses.
* fix(pipewire): drop PyAudio requirement for PipeWire sources, rebind source after reconnect
* docs(pipewire): restore PipeWireCaptureSource class docstring
* fix(audio): initialize PyAudio for mic reconnection after PipeWire session
A session started on a PipeWire sink never creates a PyAudio instance;
when capture later reconnects onto a PortAudio device the source needs
one to reopen, and a failed open dereferenced None calling terminate.
* fix(audio): harden PipeWire source resolution, reads, and cleanup
- resolve stored names by node.name/description; a stored name that no
longer resolves never falls back to a positional index
- require pw-record before listing system-audio sources in the picker
- bound pw-record chunk reads with a stall watchdog so stopping cannot
block on a wedged stream
- close the reconnection probe stream when its verification read fails
- log cleanup failures instead of swallowing them; narrow exception
handlers in enumeration and PyAudio reconnection init
- annotate test helpers and signatures per repo style
---------
Co-authored-by: Jatin K Malik <jatinkrmalik@gmail.com>