2. 语音信号基础

做语音算法这些年,我最大的感受是:很多人一上来就调模型、跑网络,结果连麦克风采出来的数据长什么样都没搞清楚。说白了,语音信号处理不是玄学,它背后有一套扎实的物理和数学基础。这一章我们就把这些底层的概念捋清楚。

声音的物理特性:从振动到数字

声音的本质是什么?是空气分子的振动。你说话的时候,声带在振动,带动周围的空气分子一推一拉,形成疏密波。这个波传到麦克风的振膜上,振膜跟着动,就把声压变化转换成了电信号。

描述这个波,有三个核心参数:

  • 频率(Frequency):每秒振动的次数,单位是赫兹(Hz)。人耳能听到的大概是 20 Hz 到 20 kHz。语音信号的能量主要集中在 300 Hz 到 3.4 kHz 这个区间——这也是传统电话系统设计的依据。
  • 幅度(Amplitude):振动的强弱,决定了音量大小。在数字信号里,幅度就是采样点的数值。
  • 相位(Phase):振动在时间轴上的起始位置。相位对人耳感知的影响没那么直接,但在阵列信号处理、波束成形里,相位差就是定位声源的关键。

关键认知:语音信号的本质是一个随时间变化的空气压力波。麦克风把它变成电压信号,ADC(模数转换器)再把它变成一串数字。你写的每一行降噪代码,最终处理的都是这串数字。

时域与频域表示:同一件事的两种视角

时域和频域,就像一枚硬币的两面。时域告诉你“信号在某个时刻有多大”,频域告诉你“信号里包含了哪些频率成分”。

我在项目中遇到过这样一个场景:一个降噪算法在时域里怎么调参数都压不住某种低频噪声。后来我把信号切到频域一看,发现那个噪声集中在 50 Hz 附近——典型的工频干扰。在频域里做个陷波滤波器,问题就解决了。你看,换个视角,解法就出来了。

时域表示

时域就是横轴为时间、纵轴为幅度的波形图。你录一段语音,用 Python 的 matplotlib 画出来,就是时域波形。它直观,但信息密度低——你很难从波形里看出这段语音是男声还是女声,更看不出背景里有没有噪声。

频域表示

频域是通过傅里叶变换得到的。把时域信号分解成不同频率的正弦波之和,每个频率对应一个幅度和相位。频谱图就是横轴为频率、纵轴为幅度的图。

举个例子,一个 440 Hz 的纯音(钢琴的 A4 音),在时域里是一条正弦波,在频域里就是一根竖线。一段语音在频域里则是一大片能量分布——元音有清晰的共振峰结构,辅音的能量则更分散。

我的习惯:做语音增强时,我几乎不会只看时域波形。频谱图(spectrogram)才是我的主力工具。它把时间、频率、幅度三个维度放在一张图上,一眼就能看出噪声和语音在时频域上的分布差异。

采样与量化:连续世界到离散数字的桥梁

麦克风出来的信号是连续的模拟信号,计算机只能处理离散的数字。这个转换过程叫 ADC,包含两个关键步骤:采样和量化。

采样

采样就是在时间轴上每隔一个固定的间隔取一个点。这个间隔的倒数就是采样率,单位是 Hz。

采样定理(奈奎斯特-香农定理)告诉我们:要无失真地重建一个信号,采样率必须至少是信号最高频率的两倍。语音信号最高频率通常按 8 kHz 算(电话语音),所以 16 kHz 的采样率是语音处理的标配。音乐信号最高频率到 20 kHz,所以 CD 用 44.1 kHz。

我曾经踩过的坑:有一次做远场语音识别,我用的麦克风阵列采样率是 16 kHz,但没注意前端有个低通滤波器的截止频率设成了 10 kHz。结果 8 kHz 以上的语音成分被严重衰减,识别率直接掉了十几个点。后来我养成了一个习惯:拿到任何音频数据,第一件事就是检查采样率和抗混叠滤波器的设置。

量化

量化是把采样得到的连续幅度值映射到有限个离散的等级上。每个等级用一个二进制数表示,这个二进制数的位数就是位深(bit depth)。

常见的位深有 16 bit 和 24 bit。16 bit 能表示 65536 个等级,动态范围大约是 96 dB。对于语音来说,16 bit 已经足够。24 bit 的动态范围更大,常用于音乐制作。

量化会引入量化噪声。简单说,就是真实值和量化值之间的误差。位深每增加 1 bit,信噪比提升约 6 dB。

参数 典型值 说明
采样率 16 kHz 语音处理标准,覆盖 0-8 kHz 频段
位深 16 bit 动态范围 96 dB,满足语音需求
声道数 1(单声道) 语音处理通常用单声道,阵列处理用多声道

语音信号的非平稳特性

这是语音信号最核心、也最容易被忽视的特性。你想想看,一段音乐你可以说它是平稳的——它的统计特性在几秒内基本不变。但语音不是这样。

语音信号是非平稳的。什么意思?它的频谱特性随时间快速变化。一个音节可能只持续几十毫秒,元音和辅音的频谱结构完全不同。清音(如 /s/、/sh/)的波形像噪声,没有明显的周期性;浊音(如 /a/、/i/)则有明显的基频周期。

为什么会这样?因为人的发声器官在不停地运动。声带的张弛、舌头的位置、嘴唇的形状,都在毫秒级的时间尺度上变化。这些变化直接反映在语音信号的频谱上。

那怎么办?我们做语音算法时,通常假设信号在很短的时间内(10-30 毫秒)是平稳的。这个假设叫短时平稳性。基于这个假设,我们把语音信号切成一小段一小段的帧,每帧 20 毫秒左右,然后对每一帧单独做分析。

实践要点:帧长一般取 20-30 毫秒,帧移取 10 毫秒(即相邻帧有 50% 的重叠)。加窗(如汉明窗)是为了减少帧边界处的频谱泄漏。这些参数直接影响后续的降噪效果——帧太短,频率分辨率不够;帧太长,非平稳性假设就不成立了。

下面这张图展示了语音信号从物理世界到数字处理的完整流程,以及时域、频域、非平稳特性之间的关系。

语音信号基础与处理流程 语音信号基础与处理流程 物理世界 声带振动 → 空气声波 传感器 麦克风 → 电信号 ADC 转换 采样 + 量化 数字信号 离散时间序列 时域表示 波形图:幅度 vs 时间 频域表示 频谱:幅度 vs 频率 非平稳特性 频谱随时间快速变化 短时平稳假设:10-30ms 帧内近似平稳

你看这个流程:物理世界的声波经过麦克风变成电信号,ADC 采样量化后变成数字信号。数字信号可以从时域和频域两个角度去分析。而语音的非平稳特性,迫使我们采用短时分析的方法——把信号切成帧,假设每帧内是平稳的,然后逐帧处理。

这个思路贯穿了整个语音算法体系。降噪、语音增强、语音识别、声源定位……几乎所有算法都建立在这个框架之上。所以,别觉得这些基础概念枯燥。你理解得越深,后面调参、debug 的时候就越有底气。