"""Quick microphone tests. Run: uv run python test_mic.py""" import numpy as np import sounddevice as sd import sys import time SAMPLE_RATE = 16000 def test_device_info(): """Show which device will be used for recording.""" default_input = sd.default.device[0] info = sd.query_devices(default_input) print(f"Default input device [{default_input}]: {info['name']}") print(f" Max input channels: {info['max_input_channels']}") print(f" Default sample rate: {info['default_samplerate']}") assert info["max_input_channels"] > 0, "Default device has no input channels!" print(" PASS\n") def test_record_1s(): """Record 1 second and check we got non-silent audio.""" print("Recording 1 second... (speak or make noise!)") audio = sd.rec(SAMPLE_RATE, samplerate=SAMPLE_RATE, channels=1, dtype="float32") sd.wait() audio = audio.flatten() peak = np.max(np.abs(audio)) rms = np.sqrt(np.mean(audio ** 2)) print(f" Samples: {len(audio)}") print(f" Peak amplitude: {peak:.4f}") print(f" RMS: {rms:.6f}") assert len(audio) == SAMPLE_RATE, f"Expected {SAMPLE_RATE} samples, got {len(audio)}" assert peak > 0, "All zeros — mic not capturing anything" if peak < 0.001: print(" WARNING: Very low signal — mic might be muted or too far away") else: print(" Signal level looks good") print(" PASS\n") def test_record_levels(): """Record 3 seconds in 1-second chunks, show live levels.""" print("Recording 3 seconds — speak during seconds 2-3 for comparison...") for i in range(3): audio = sd.rec(SAMPLE_RATE, samplerate=SAMPLE_RATE, channels=1, dtype="float32") sd.wait() audio = audio.flatten() rms = np.sqrt(np.mean(audio ** 2)) peak = np.max(np.abs(audio)) bar = "#" * int(min(peak * 200, 50)) print(f" Second {i+1}: peak={peak:.4f} rms={rms:.6f} |{bar}") print(" PASS\n") def test_stream_callback(): """Test that InputStream callback fires correctly.""" frames_received = [] def callback(indata, frames, time_info, status): if status: print(f" Status: {status}") frames_received.append(len(indata)) print("Testing InputStream callback for 1 second...") with sd.InputStream(samplerate=SAMPLE_RATE, channels=1, dtype="float32", callback=callback, blocksize=800): time.sleep(1) total_frames = sum(frames_received) expected = SAMPLE_RATE print(f" Callbacks fired: {len(frames_received)}") print(f" Total frames: {total_frames} (expected ~{expected})") print(f" Blocksize per callback: {frames_received[0] if frames_received else 'N/A'}") assert len(frames_received) > 0, "No callbacks received!" assert abs(total_frames - expected) < expected * 0.2, f"Frame count off by >20%" print(" PASS\n") if __name__ == "__main__": print("=== Microphone Tests ===\n") test_device_info() test_record_1s() test_record_levels() test_stream_callback() print("All tests passed!")