You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

scipy.rfft分析电脑音频时检测频率为预期值一半的问题咨询

问题原因

你遇到的频率减半、存在镜像峰的问题,核心原因是读取立体声音频流时直接按单声道序列做了解码处理:

  • Pyaudio默认开启的音频流为双声道(立体声)格式,每个音频帧包含左、右两个通道的16位采样值
  • 你调用stream.read(int(self.sampleRate/10))拿到的缓冲区,对应sampleRate/10个立体声帧,用np.frombuffer(..., np.int16)解码后得到的数组长度是2*sampleRate/10,是实际单声道采样帧数的两倍
  • 将两倍长度的数组传入rfft计算时,rfftfreq用错误的序列长度计算频率轴,最终得到的频率值只有实际值的一半;而你观测到的12kHz镜像峰,刚好对应44100Hz采样率的奈奎斯特频率(22050Hz)减去原始10kHz信号的频率值,是序列拼接错误带来的典型混叠伪影。

修复方案

方案1:流读取后转单声道

如果你的流本身就是立体声配置,解码后提取单通道数据再做FFT即可,修改读取代码如下:

frames = np.frombuffer(
            self.stream.read(int(self.sampleRate/10)), np.int16)
# 新增:提取左通道数据,也可替换为 frames[1::2] 取右通道,或左右通道平均
frames = frames[::2]
xf, yf = audioUtils.getSpectrum(frames, self.sampleRate)
self.plotWidget.plot(xf, yf)

方案2:直接开启单声道流

在初始化Pyaudio流时,将channels参数设置为1,只要你使用的分支支持单声道环回录制,读取的缓冲区就直接是单声道采样,无需额外处理。

验证方法

你可以打印解码后的len(frames)值确认问题:如果未做处理时长度是8820(对应44100Hz采样率下0.1秒的立体声数据),处理后变为4410,就说明问题根因确实是立体声未转单声道。

内容的提问来源于stack exchange,提问作者Cyrano Chatziantoniou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 05:45:03