Sample Rate Change by GNURadio

一句话:插值把采样率抬高、可用带宽变大,但代价是会产生频谱镜像——必须配一个低通滤波器把它滤掉。

一、背景:为什么要改变采样率

奈奎斯特告诉我们:采样率决定了能表示的最高频率(约等于采样率的一半)。所以当你需要”看到”更宽的频谱、或者让后续模块能处理更高频的信号时,最直接的办法就是把采样率抬上去。

抬采样率的操作叫插值(Interpolation)。但天下没有免费的午餐——插值会在频谱里引入一堆”镜像”,不处理的话波形会失真。这篇文章就做两件事:插值升采样,以及把镜像滤掉。

二、原理:插值 = 升采样 + 低通滤镜像

用大白话说:原来 1 秒只有 100 个采样点,插值后变成 1 秒 400 个点(插值倍数 = 4)。

数学上插值的步骤是:

  1. 补零升采样:在每两个原始点之间插 3 个 0,采样率变成 4 倍;
  2. 低通滤波:补零会在频域产生周期性的镜像,用一个低通滤波器把镜像滤掉,只保留基带。

所以”插值”和”低通滤波”是天生绑定的——GNURadio 里的 Interpolating FIR Filter 就把这两件事一起做了。

对应地,另外两个概念:

  • 抽取(Decimation)= 低通防混叠 + 降采样
  • 重采样(Resampling)= 插值 + 抽取,实现任意速率变换

三、动手:复现步骤

1. 需要的 block

  • Two Variable blocks(两个变量)
  • Low-Pass Filter Taps(生成滤波器抽头)
  • QT GUI Range(频率滑块)
  • Signal Source(信号源)
  • Interpolating FIR Filter(插值 + 滤波)
  • Throttle(限速)
  • QT GUI Frequency Sink(看频谱)

按下面的方式连接:

2. 变量设置

变量一

  • Id:interpolation_rate
  • Value:4

变量二

  • Id:samp_rate_interpolated
  • Value:samp_rate * interpolation_rate

注意变量名要和引用一致,写错一个字母 GNURadio 会直接报 “Variable not defined”。这里 samp_rate 是内置变量。

3. 滤波器设置(关键)

Low-Pass Filter Taps

  • Id:lowPassTaps
  • Sample Rate:samp_rate_interpolated
  • Cutoff Freq:samp_rate_interpolated / (interpolation_rate * 2)
  • Transition Width:samp_rate_interpolated / (interpolation_rate * 4)

为什么截止频率要这么算? 插值后采样率变成了原来的 4 倍,镜像出现在原始带宽的边界之外。截止频率取”插值后采样率 ÷ (2×插值倍数)”,正好落在原始奈奎斯特边界上,能把镜像挡在外面又不伤基带。这里所有频率都按插值后的采样率计算,这是最容易算错的地方。

QT GUI Range

  • Id:frequency
  • Default Value:0
  • Start:-samp_rate/2
  • Stop:samp_rate/2

Signal Source

  • Frequency:frequency

Interpolating FIR Filter

  • Interpolation:interpolation_rate
  • Taps:lowPassTaps

Throttle

  • Sample Rate:samp_rate_interpolated

Throttle 的采样率必须跟着插值后的速率走,否则限速逻辑和实际数据流对不上。

QT GUI Frequency Sink

  • Bandwidth:samp_rate_interpolated

4. 运行验证

运行后观察频谱:插值后采样率变高,频谱展示范围明显变宽,波形也更平滑。

四、常见坑与边界

  • 滤波器截止频率必须按插值后的采样率算。很多人习惯性沿用原始 samp_rate,结果滤波器通带被压得太窄或镜像没滤干净。
  • 插值倍数越高,滤波器阶数越高。过渡带宽越小,需要的 FIR 抽头越多,计算量越大;倍数开太大会明显吃 CPU。
  • Throttle 的采样率要和数据流一致,否则要么限速失效要么报错。
  • 不滤波直接插值 = 频谱全是镜像,波形看起来”毛刺”,这就是漏掉低通滤波的典型症状。
  • 变量引用要成对检查:samp_rate_interpolated 依赖 samp_rate,变量定义顺序和拼写都要对。

五、结论

一句话记住三者关系:

  • 插值 = 升采样 + 低通滤镜像(抬高采样率、扩大可用带宽)
  • 抽取 = 低通防混叠 + 降采样
  • 重采样 = 插值 + 抽取

Interpolating FIR Filter 把”插值”和”滤波”打包在一起,所以只要用它,就必须同时想清楚抽头(Taps)是怎么来的——而抽头的截止频率,永远跟着插值后的采样率走。