"""Utility to diagnose Bumble SoundDeviceAudioInput compatibility. Run inside the project venv: python -m tests.usb_audio_diag [rate] It enumerates all PortAudio input devices and tries to open each with Bumble's create_audio_input using the URI pattern `device:` with an explicit input_format of `int16le,,1`. """ from __future__ import annotations import asyncio import sys import sounddevice as sd # type: ignore from bumble.audio import io as audio_io # type: ignore RATE = int(sys.argv[1]) if len(sys.argv) > 1 else 48000 aSYNC = asyncio.run async def try_device(index: int, rate: int = 48000) -> None: input_uri = f"device:{index}" try: audio_input = await audio_io.create_audio_input(input_uri, f"int16le,{rate},1") fmt = await audio_input.open() print(f"\033[32m✔︎ {input_uri} -> {fmt.channels}ch @ {fmt.sample_rate}Hz\033[0m") if hasattr(audio_input, "aclose"): await audio_input.aclose() except Exception as exc: # pylint: disable=broad-except print(f"\033[31m✗ {input_uri}: {exc}\033[0m") async def main() -> None: print(f"Trying PortAudio input devices with rate {RATE} Hz\n") for idx, dev in enumerate(sd.query_devices()): if dev["max_input_channels"] > 0 and "(hw:" in dev["name"].lower(): name = dev["name"] print(f"[{idx}] {name}") await try_device(idx, RATE) print() if __name__ == "__main__": aSYNC(main())