如何通过整数除法实现任意比例采样率降低?以80kHz转50kHz为例
非整数比例实时降采样实现思路(80000Hz → 50000Hz)
首先咱们把问题拆解清楚:你要把80000Hz的采样率降1.6倍到50000Hz,核心是用类似整数除法/预分频器的思路,通过实时跳过采样点来实现,而且不能改变信号本身的频率对吧?
第一步:把非整数比例转换成整数分数
1.6倍的降采样比例,其实可以写成8/5(因为80000 ÷ 1.6 = 50000,等价于80000 × 5/8 = 50000)。换句话说,我们需要每输入8个采样点,就输出其中的5个,长期下来平均采样率就刚好是目标的50000Hz。
第二步:用累加计数器实现实时采样选择
这个思路和预分频器的工作逻辑完全一致——用一个整数累加器代替浮点运算,每次输入采样时更新计数器,达到阈值就输出当前采样,否则跳过。具体步骤如下:
- 初始化一个整数累加器
accumulator = 0 - 定义两个常量:
INPUT_SCALE = 8(对应原采样率的比例系数)、OUTPUT_SCALE =5(对应目标采样率的比例系数) - 每次调用
new_sample()时:- 把累加器加上
OUTPUT_SCALE - 如果累加器的值大于等于
INPUT_SCALE,就输出当前采样,同时把累加器减去INPUT_SCALE - 如果累加器没到阈值,直接跳过当前采样
- 把累加器加上
代码示例(C语言风格)
// 全局或静态变量,用于保存累加状态 int accumulator = 0; // 比例系数:80000/50000 = 8/5 const int INPUT_SCALE = 8; const int OUTPUT_SCALE = 5; // 输入一个采样,返回是否有输出采样,输出结果存在output_sample中 bool new_sample(int16_t input_sample, int16_t *output_sample) { accumulator += OUTPUT_SCALE; if (accumulator >= INPUT_SCALE) { *output_sample = input_sample; accumulator -= INPUT_SCALE; return true; // 本次有输出采样 } return false; // 本次跳过采样,无输出 }
为什么这个方法可行?
- 纯整数运算:完全避免浮点计算,适合嵌入式、实时系统,和预分频器的硬件逻辑对齐
- 实时性拉满:每个采样只做一次加法和比较,不需要缓存大量数据
- 比例绝对精确:长期来看,每8个输入采样必然输出5个,平均采样率严格是80000×5/8=50000Hz
⚠️ 注意:因为是欠采样,一定要确保原信号的最高频率不超过目标采样率的奈奎斯特频率(也就是25000Hz),否则会出现混叠失真。如果原信号有高频成分,记得先加低通滤波器再做降采样哦。
内容的提问来源于stack exchange,提问作者miXo
相关产品推荐
相关产品推荐

