如何用PyAudio录制8位音频?paInt8/paUInt8录制仅出噪音问题
PyAudio使用paInt8/paUInt8格式时仅录制噪音的问题
问题情况
PyAudio使用pyaudio.paInt16格式时音频录制/播放正常,但切换到pyaudio.paInt8或pyaudio.paUInt8格式后,只能听到噪音,即使关闭麦克风,录制的内容也完全固定不变。
相关代码
p = pyaudio.PyAudio() inStream = p.open(format=pyaudio.paInt8, channels=1, rate=8000, input=True) outStream = p.open(format=pyaudio.paInt8, channels=1, rate=8000, output=True) print(p.get_default_input_device_info()) while True: data = inStream.read(160) print(data) # outStream.write(data)
麦克风设备信息
{'index': 1, 'structVersion': 2, 'name': 'Headset Microphone (INZONE H9 /', 'hostApi': 0, 'maxInputChannels': 1, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}
录制的固定音频数据
b'\x14\x00\x00\x00\x00\x00\x00\x00p;\xfd\xcc\xd0\x01\x00\x00\xf0<\xfd\xcc\xd0\x01\x00\x00\xf0;\xfd\xcc\xd0\x01\x00\x00\xb06\xfd\xcc\xd0\x01\x00\x000\xb5\x1b\xcf\xd0\x01\x00\x00\x90\xe4\x1b\xcf\xd0\x01\x00\x000\x05\xfd\xcc\xd0\x01\x00\x00pq\xff\xcc\xd0\x01\x00\x00\xc0+\x1b\xcf\xd0\x01\x00\x00\x10,\x1b\xcf\xd0\x01\x00\x00p\xbc\x1b\xcf\xd0\x01\x00\x00\xb0\xbc\x1b\xcf\xd0\x01\x00\x000\xbb\x1b\xcf\xd0\x01\x00\x00\xf0\xbc\x1b\xcf\xd0\x01\x00\x000\xbd\x1b\xcf\xd0\x01\x00\x00p\xbd\x1b\xcf\xd0\x01\x00\x00pr\xff\xcc\xd0\x01\x00\x00\xb0\x1f\x05\xcd\xd0\x01\x00\x00\xa0\xe3\x1b\xcf\xd0\x01\x00\x00'
问题原因分析
- 硬件/驱动不支持8位采样:绝大多数现代麦克风原生仅支持16位及以上采样深度,PyAudio的软件模拟8位格式时易出现数据转换错误,导致输出固定噪音。
- 采样率不匹配:设备默认采样率为44100Hz,但代码中强制使用8000Hz,低深度格式下的采样率转换更容易引入失真或错误数据。
- 数据格式对齐错误:8位格式的字节对齐方式与设备原生输出不兼容,导致读取到的是无效的固定数据。
解决方案
方案1:使用设备原生支持的格式(推荐)
直接使用设备原生的pyaudio.paInt16格式和默认采样率44100Hz,避免格式转换带来的问题:
p = pyaudio.PyAudio() inStream = p.open(format=pyaudio.paInt16, channels=1, rate=44100, input=True) outStream = p.open(format=pyaudio.paInt16, channels=1, rate=44100, output=True) while True: data = inStream.read(1024) outStream.write(data)
方案2:录制16位后手动转换为8位
如果必须使用8位格式,先以16位录制,再手动转换为8位,避免硬件层面的格式不兼容:
import pyaudio import numpy as np p = pyaudio.PyAudio() # 用16位格式录制 inStream = p.open(format=pyaudio.paInt16, channels=1, rate=44100, input=True, frames_per_buffer=1024) # 用8位格式输出 outStream = p.open(format=pyaudio.paInt8, channels=1, rate=44100, output=True) while True: data = inStream.read(1024) # 转换为numpy数组处理 audio_16bit = np.frombuffer(data, dtype=np.int16) # 转换为8位:16位范围是-32768~32767,8位是-128~127,做缩放 audio_8bit = (audio_16bit / 256).astype(np.int8) # 转换回字节流输出 outStream.write(audio_8bit.tobytes())
内容的提问来源于stack exchange,提问作者conata
相关产品推荐
相关产品推荐

