使用Python将NAO机器人麦克风音频流传输到PC的故障求助
NAO机器人音频流杂音问题修复方案
错误原因
- 采样率参数传错:PyAudio打开流时的
rate参数传入了nbrOfSamplesByChannel,该值为单次回调返回的单通道采样数,不是采样率,应填入你预设的16000。nbrOfSamplesByChannel=1365是正常返回值,16000采样率下170ms双声道缓冲区拆分到单通道就是约1365个采样点,和你设置的采样率没有关系,无需修改。 - 采样格式不匹配:NAO返回的音频是16位整型采样,你使用
p.get_format_from_width(1)对应8位采样,格式错位直接导致杂音,应改为p.get_format_from_width(2)。 - 流初始化逻辑错误:每次
processRemote回调都重新创建PyAudio实例和播放流,会引发资源泄漏、音频断帧,应该把PyAudio和播放流的初始化逻辑放到start方法中,回调函数里只写入最新的音频数据即可。 - 输出数据错误:你当前回调返回的原始
buffer_audio是交错格式数据,单声道输出时需要提取aSoundData[0]转换为字节流后输出。
修正代码示例
import naoqi import numpy as np import pyaudio class SoundReceiverModule: def __init__(self, strNaoIp): self.strNaoIp = strNaoIp self.p = None self.stream = None self.nSampleRate = 16000 def start(self): # 初始化NAO音频代理 audio = naoqi.ALProxy("ALAudioDevice", self.strNaoIp, 9559) nNbrChannelFlag = 3 # 单前向麦克风 nDeinterleave = 0 audio.setClientPreferences(self.getName(), self.nSampleRate, nNbrChannelFlag, nDeinterleave) audio.subscribe(self.getName()) # 初始化PyAudio流,仅执行一次 self.p = pyaudio.PyAudio() self.stream = self.p.open( format=self.p.get_format_from_width(2), channels=1, rate=self.nSampleRate, output=True ) print("INF: SoundReceiver: started!") def processRemote(self, nbOfChannels, nbrOfSamplesByChannel, aTimeStamp, buffer_audio): aSoundDataInterlaced = np.frombuffer(buffer_audio, dtype=np.int16) aSoundData = np.reshape(aSoundDataInterlaced, (nbOfChannels, nbrOfSamplesByChannel), 'F') # 单声道取第一个通道的数据写入流 self.stream.write(aSoundData[0].tobytes()) # 峰值检测按需保留 aPeakValue = np.max(aSoundData) if aPeakValue > 16000: print("Peak: %s" % aPeakValue)
缓冲区说明
ALAudioDevice的170ms缓冲区是底层固定配置,上层不需要手动处理,只要保证回调返回的采样数据能及时喂给播放流即可,和你当前遇到的音频异常无关。
内容的提问来源于stack exchange,提问作者Pavel Vican
相关产品推荐
相关产品推荐

