test_audio_devices.py 5.48 KB
# AIfeng/2025-07-07 10:25:00
# 音频设备检测和录音测试脚本

import pyaudio
import numpy as np
import time
import threading

def list_audio_devices():
    """列出所有可用的音频设备"""
    audio = pyaudio.PyAudio()
    print("=== 音频设备列表 ===")
    
    input_devices = []
    for i in range(audio.get_device_count()):
        device_info = audio.get_device_info_by_index(i)
        if device_info['maxInputChannels'] > 0:
            input_devices.append({
                'index': i,
                'name': device_info['name'],
                'channels': device_info['maxInputChannels'],
                'sample_rate': device_info['defaultSampleRate']
            })
            print(f"设备 {i}: {device_info['name']}")
            print(f"  输入声道: {device_info['maxInputChannels']}")
            print(f"  默认采样率: {device_info['defaultSampleRate']}")
            print(f"  主机API: {audio.get_host_api_info_by_index(device_info['hostApi'])['name']}")
            print()
    
    audio.terminate()
    return input_devices

def test_microphone_volume(device_index=None, duration=5):
    """测试麦克风音量检测"""
    print(f"\n=== 麦克风音量测试 (设备: {device_index if device_index is not None else '默认'}) ===")
    print(f"测试时长: {duration}秒")
    print("请对着麦克风说话...")
    
    audio = pyaudio.PyAudio()
    
    # 音频参数
    chunk = 1024
    format = pyaudio.paInt16
    channels = 1
    rate = 16000
    
    try:
        # 创建音频流
        stream = audio.open(
            format=format,
            channels=channels,
            rate=rate,
            input=True,
            input_device_index=device_index,
            frames_per_buffer=chunk
        )
        
        print("开始录音...")
        start_time = time.time()
        max_volume = 0
        volume_samples = []
        
        while time.time() - start_time < duration:
            try:
                # 读取音频数据
                data = stream.read(chunk, exception_on_overflow=False)
                
                # 转换为numpy数组并计算音量
                audio_data = np.frombuffer(data, dtype=np.int16)
                volume = np.sqrt(np.mean(audio_data.astype(np.float32) ** 2)) / 32768.0
                
                volume_samples.append(volume)
                max_volume = max(max_volume, volume)
                
                # 实时显示音量
                bar_length = int(volume * 50)
                bar = '█' * bar_length + '░' * (50 - bar_length)
                print(f"\r音量: {volume:.4f} [{bar}]", end="", flush=True)
                
            except Exception as e:
                print(f"\n读取音频数据错误: {e}")
                break
        
        print(f"\n\n=== 测试结果 ===")
        print(f"最大音量: {max_volume:.4f}")
        print(f"平均音量: {np.mean(volume_samples):.4f}")
        print(f"音量标准差: {np.std(volume_samples):.4f}")
        
        if max_volume < 0.001:
            print("⚠️  警告: 检测到的音量极低,可能存在以下问题:")
            print("   1. 麦克风未正确连接")
            print("   2. 麦克风被静音")
            print("   3. 选择了错误的音频设备")
            print("   4. 麦克风权限被拒绝")
        elif max_volume < 0.01:
            print("⚠️  警告: 音量较低,建议检查麦克风设置")
        else:
            print("✅ 麦克风工作正常")
        
        stream.stop_stream()
        stream.close()
        
    except Exception as e:
        print(f"\n❌ 音频流创建失败: {e}")
        print("可能的原因:")
        print("  1. 设备不支持指定的音频格式")
        print("  2. 设备被其他程序占用")
        print("  3. 权限不足")
    
    finally:
        audio.terminate()

def main():
    print("音频设备检测和录音测试工具")
    print("作者: AIfeng")
    print("时间: 2025-07-07 10:25:00")
    print("=" * 50)
    
    # 列出音频设备
    devices = list_audio_devices()
    
    if not devices:
        print("❌ 未找到可用的音频输入设备")
        return
    
    print(f"找到 {len(devices)} 个音频输入设备")
    
    # 测试默认设备
    print("\n1. 测试默认音频设备")
    test_microphone_volume(device_index=None, duration=3)
    
    # 如果有多个设备,让用户选择测试
    if len(devices) > 1:
        print("\n2. 选择特定设备测试")
        print("可用设备:")
        for i, device in enumerate(devices):
            print(f"  {device['index']}: {device['name']}")
        
        try:
            choice = input("\n请输入设备编号进行测试 (回车跳过): ").strip()
            if choice:
                device_index = int(choice)
                if any(d['index'] == device_index for d in devices):
                    test_microphone_volume(device_index=device_index, duration=5)
                else:
                    print(f"❌ 设备编号 {device_index} 不存在")
        except ValueError:
            print("❌ 无效的设备编号")
        except KeyboardInterrupt:
            print("\n测试被用户中断")
    
    print("\n=== 建议 ===")
    print("1. 确保麦克风已正确连接并开启")
    print("2. 检查系统音频设置中的麦克风权限")
    print("3. 尝试在其他应用中测试麦克风是否工作")
    print("4. 如果使用外接麦克风,检查驱动程序是否正确安装")

if __name__ == "__main__":
    main()