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

FFT与窗函数执行顺序咨询——压电传感器吉他电压采集项目

问题解答

核心结论

必须先对采集到的时域电压信号应用窗函数,再执行FFT,绝对不能反过来操作。

原因解释

FFT的数学前提是输入信号是严格周期性的,但你采集的吉他发声信号是瞬态的(拨弦后声音逐渐衰减),而且采集的信号片段不可能刚好是完整周期的整数倍。直接对这类信号做FFT会产生频谱泄漏——原本集中在单一频率的能量会扩散到相邻频率上,导致噪声干扰、频谱精度下降。

窗函数的作用就是通过平滑信号的首尾边缘,让截断后的信号更接近周期性,从而大幅减少频谱泄漏。如果先做FFT再加窗,相当于对频域信号做滤波,完全起不到抑制泄漏的作用,反而会破坏真实的频谱信息。

Python实现示例

针对你的吉他信号采集场景,推荐使用汉宁窗(Hanning Window)或布莱克曼窗(Blackman Window),这两种窗在抑制频谱泄漏和保留频率精度之间的平衡较好。以下是基础实现步骤:

  1. 导入必要库
import numpy as np
  1. 读取采集到的电压数据(替换成你从压电传感器获取的实际数据)
# 假设采样率为44100Hz(音频常用采样率),采集固定长度的信号
sample_rate = 44100
num_samples = 1024  # 取2的整数次方,FFT计算更快

# 实际项目中替换为从传感器读取数据的代码,比如:
# raw_signal = pi_adc.read_samples(num_samples)
raw_signal = np.random.normal(0, 0.5, num_samples)  # 模拟传感器数据+噪声
  1. 应用窗函数并执行FFT
# 生成汉宁窗
window = np.hanning(num_samples)
# 对原始信号加窗
windowed_signal = raw_signal * window

# 执行FFT并处理结果
fft_result = np.fft.fft(windowed_signal)
# 计算频率轴
freq_axis = np.fft.fftfreq(num_samples, 1/sample_rate)
# 提取正频率部分的幅度值(转换为相对幅度)
positive_mask = freq_axis >= 0
fft_magnitude = np.abs(fft_result[positive_mask]) / num_samples
positive_freqs = freq_axis[positive_mask]
  1. 适配LCD显示的简化处理
# 截取吉他核心频段(比如0-1000Hz)
target_mask = positive_freqs <= 1000
display_freqs = positive_freqs[target_mask]
display_mag = fft_magnitude[target_mask]

# 将幅度值映射到LCD的像素高度范围(比如0-60)
max_mag = np.max(display_mag) if np.max(display_mag) != 0 else 1
display_mapped = (display_mag / max_mag) * 60

# 后续即可将display_mapped的数据输出到LCD显示频谱柱状图

额外建议

  • 采样率建议设置为44100Hz或48000Hz,这是音频领域的标准采样率,能完整捕捉吉他的所有频率成分。
  • 如果LCD屏幕尺寸有限,可以对FFT结果做降采样,只保留关键频率点的幅度值,避免显示拥挤。

内容的提问来源于stack exchange,提问作者Roger Fed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 12:31:00