"""Audio playback for WAV files.""" import asyncio import io import logging import numpy as np import sounddevice as sd import soundfile as sf logger = logging.getLogger(__name__) def play_wav(wav_data: bytes, volume: int = 100) -> None: data, samplerate = sf.read(io.BytesIO(wav_data), dtype="float32") if volume != 100: gain = max(0.0, volume / 100.0) data = np.clip(data * gain, -1.0, 1.0) sd.play(data, samplerate) sd.wait() async def play_wav_async(wav_data: bytes, volume: int = 100) -> None: loop = asyncio.get_running_loop() await loop.run_in_executor(None, play_wav, wav_data, volume) def get_output_devices() -> list[dict]: devices = sd.query_devices() result = [] for i, dev in enumerate(devices): if dev["max_output_channels"] > 0: result.append({ "index": i, "name": dev["name"], "channels": dev["max_output_channels"], "default_samplerate": dev["default_samplerate"], }) return result