采样率不同的两路音频要先对齐采样率才能合到一起;重采样的关键不是插值,而是先低通滤波,否则会出现混叠。
4.1.7 讲混音时提到【两路要先对齐】,这一节把这一步单独讲清楚。
一、什么情况要重采样
三种情况会逼着你做这件事: 采样率不同——44.1 kHz 的音乐要和 48 kHz 的语音混在一起。 声道数不同——单声道话筒要配进立体声轨道。 格式不同——一段来自不同来源的素材要统一。 只要两路音频要【合到一起】,就必须先站在同一个采样率上。
二、44.1 kHz 转 48 kHz 是怎么算的
两个采样率之比可以约成最简整数比:44100 : 48000 = 147 : 160。 意思是:每 147 个输入采样点,要变成 160 个输出采样点。 这就是重采样可以精确完成的原因——整数比意味着可以用规则的方式插值。 如果两个采样率之比不是有理数,就得用近似,误差会明显一些。
三、升采样与降采样
升采样(44.1 → 48,变多):要在采样点之间插值补出新点。 降采样(48 → 44.1,变少):要抽掉一部分点。 两种都要经过一次滤波——这一步才是重采样真正的技术含量所在。 很多人以为重采样就是插值,其实插值只是其中一步。
四、混叠:最关键的一步
采样定理说:采样率要大于信号最高频率的 2 倍。 48 kHz 的音频里可以含有 24 kHz 的成分,但 44.1 kHz 的输出只能容下 22.05 kHz。 如果直接把超出的部分抽掉不处理,它们会【折回】到可听范围,变成刺耳的杂音。 这个现象叫混叠(aliasing)。 所以重采样的正确做法是:先做低通滤波,把超出的高频切干净,再重采样。
五、动手 Demo:44.1 kHz 转 48 kHz 发生了什么
采样率不一样的两段音频,必须先对齐采样率才能混在一起。
import math
src, dst = 44100, 48000
g = math.gcd(src, dst)
print("%d : %d = %d : %d" % (src, dst, src // g, dst // g))
print("每 %d 个输入采样点 -> %d 个输出采样点" % (src // g, dst // g))
for name, sr in [("44.1 kHz", 44100), ("48 kHz", 48000)]:
print(" %s 立体声 16bit -> %s 字节/秒" % (name, format(sr * 2 * 2, ",")))
实跑输出:
--------------------------------------------------------------------
44.1 kHz 转 48 kHz 发生了什么
--------------------------------------------------------------------
采样率不一样的两段音频,必须先对齐采样率才能混在一起。
44100 : 48000 = 147 : 160(最简整数比)
意思是:每 147 个输入采样点,要插值变成 160 个输出采样点。
插值不是随便补零,要**先做低通滤波再重采样**——
不滤波的话,超过 22.05 kHz 的成分会【折回】到可听范围,产生刺耳杂音。
这个现象叫**混叠**,是重采样里最经典的坑。
每秒数据量也随之变化:
44.1 kHz 立体声 16bit → 176,400 字节/秒
48 kHz 立体声 16bit → 192,000 字节/秒
插值不是随便补零,要先做低通滤波再重采样。 不滤波的话,超过 22.05 kHz 的成分会【折回】可听范围,产生刺耳杂音——这就是混叠。
30 秒实验
- 找一段 44.1 kHz 的音频转成 48 kHz,比较转换前后每秒字节数。
- 想一下:这次转换有没有重新编码,为什么。
常见误区
- 以为重采样只是补零或丢点。不滤波就会产生混叠杂音。
- 把 44.1 kHz 转 48 kHz 当成【提升音质】。它只是对齐,不会凭空造出高频。
自测三问(点开对答案)
1. 什么情况下必须重采样? —— 采样率、声道数或格式不同的音频要合到一起时。 2. 44.1 kHz 与 48 kHz 的最简整数比是多少? —— 147 : 160。 3. 重采样最关键的一步是什么? —— 抗混叠低通滤波——先把超出的高频切掉,否则会折回可听范围。- ☐ 下一节(4.2.1 音频压缩)
相关笔记
- 混音技术 — 为什么要先对齐
- 数字音频 — 采样率的由来
- FFmpeg — libswresample 干的就是这件事
- 🎬 FFmpeg入门详解 · 索引