Yocto Linux的imx8MP板上PyAudio无法录音但arecord正常
问题描述
在运行Yocto Linux的imx8MP开发板上,编写了基于PyAudio的麦克风采集Python脚本,但PyAudio无法正常工作,而arecord工具验证录音功能正常。
arecord验证正常的命令及输出
./arecord -L null Discard all samples (playback) or generate zero samples (capture) sysdefault:CARD=imxaudiosph0645 imx-audio-sph0645, Default Audio Device ./arecord -l **** List of CAPTURE Hardware Devices **** card 0: imxaudiosph0645 [imx-audio-sph0645], device 0: imx-sph0645 snd-soc-dummy-dai-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0 # 该命令执行正常,能生成有效录音文件 ./arecord -D hw:0,0 -r 32000 -f S32_LE -c 1 -d 5 -t wav -v 32000_32_1.wav
PyAudio报错信息
Python交互环境下执行代码时出现错误:
>>> stream=p.open(format=pa.paInt16, channels=1, rate=44100, frames_per_buffer=1024, input=True) ... OSError: [Errno -9999] Unanticipated host error >>> pa.pa.get_device_count() OSError: [Errno -10000] PortAudio not initialized
同时执行脚本时dmesg输出显示fsl-sai设备多次无法设置硬件参数。
系统信息
- Python 3.7.8
- PyAudio 0.2.11
- 内核版本:Linux 5.4.70+gbc47e1c1ba40
- ALSA驱动版本:k5.4.70+gbc47e1c1ba40
请问这可能是什么问题?
可能的原因及解决方向
参数不匹配
arecord使用的是32kHz采样率、S32_LE格式,而PyAudio代码里用的是44100Hz采样率、paInt16格式。imx8MP的音频硬件(sph0645+FSL SAI)可能不支持PyAudio指定的参数组合,导致硬件参数设置失败。
解决:将PyAudio的参数改成与arecord一致的配置:import pyaudio pa = pyaudio.PyAudio() stream = pa.open(format=pa.paInt32, channels=1, rate=32000, frames_per_buffer=1024, input=True)PortAudio编译时的ALSA适配问题
PyAudio依赖PortAudio,Yocto构建的PortAudio可能未正确适配imx8MP的ALSA驱动(尤其是SND_SOC架构的音频设备),或编译时未启用正确的ALSA后端选项,导致PortAudio无法识别或操作硬件设备。
解决:- 检查Yocto中PortAudio的配方(portaudio.bb),确保添加了
PACKAGECONFIG += "alsa"以启用ALSA支持,且编译时链接了目标板的ALSA库。 - 重新构建PortAudio和PyAudio包,确保适配目标板的音频硬件。
- 检查Yocto中PortAudio的配方(portaudio.bb),确保添加了
设备权限问题
虽然arecord能正常运行,但Python进程可能没有足够权限访问音频设备。
解决:- 检查
/dev/snd/*设备文件的权限,确保当前用户属于audio组。 - 临时使用
sudo运行Python脚本测试是否为权限问题。
- 检查
PortAudio初始化失败
pa.get_device_count()报错说明PortAudio未初始化成功,可能是PortAudio加载ALSA驱动时遇到底层错误,比如找不到合适的PCM设备。
解决:在PyAudio初始化时指定具体设备,避免使用默认设备:import pyaudio pa = pyaudio.PyAudio() # 遍历获取目标设备索引 target_dev_index = None for i in range(pa.get_device_count()): dev_info = pa.get_device_info_by_index(i) if 'imxaudiosph0645' in dev_info['name']: target_dev_index = i break # 指定设备打开流 if target_dev_index is not None: stream = pa.open(format=pa.paInt32, channels=1, rate=32000, frames_per_buffer=1024, input=True, input_device_index=target_dev_index)
内容的提问来源于stack exchange,提问作者firion
相关产品推荐
相关产品推荐

