共计 1849 个字符,预计需要花费 5 分钟才能阅读完成。
为什么需要 PCM 编码?
在数字通信系统中,模拟信号(比如我们的声音)需要转换成数字信号才能传输。PCM(脉冲编码调制)就是最基础的模数转换方法。但直接均匀量化会有一个大问题:小信号量化误差大,大信号却浪费精度。比如用 8bit 表示 0 -1V 的声音时,0.01V 的小信号可能被量化为 0,而 1V 的大信号却有 255 个级别可用。

A 律压缩的数学原理
A 律的压缩公式长这样:
$$F(x) = \begin{cases}
\frac{A|x|}{1+\ln A} & 0 \leq |x| \leq \frac{1}{A} \
\frac{1+\ln(A|x|)}{1+\ln A} & \frac{1}{A} \leq |x| \leq 1
\end{cases}$$
工程上采用 13 折线近似(A=87.6),好处是:
– 用 4 段正 + 4 段负 + 零共 13 段
– 硬件实现只需要比较器和移位器
– 动态范围达到 40dB 以上
手把手实现步骤
1. 信号归一化处理
假设输入信号范围是 - 1 到 1,首先要做幅度归一化:
function normalized = normalize_input(x)
max_val = max(abs(x));
normalized = x / max_val * 0.9999; % 避免边界溢出
end
2. 编码逻辑分解
-
符号位判定 :
sign_bit = (x >= 0); -
段落码查找表法 :
segment_thresholds = [0, 1/128, 1/64, 1/32, 1/16, 1/8, 1/4, 1/2]; segment_code = find(abs(x) >= segment_thresholds, 1, 'last') - 1; -
段内量化 :每段等分 16 级
step_size = (segment_thresholds(segment_code+2) - ... segment_thresholds(segment_code+1)) / 16; step_index = floor((abs(x) - segment_thresholds(segment_code+1)) / step_size);
3. 完整编码函数
function pcm_code = a_law_encoder(x)
% 输入归一化
x = normalize_input(x);
% 符号位
sign_bit = (x >= 0);
abs_x = abs(x);
% 段落判断
seg_boundaries = [0, 1/128, 1/64, 1/32, 1/16, 1/8, 1/4, 1/2, 1];
segment = find(abs_x >= seg_boundaries, 1, 'last') - 1;
% 段内量化
start = seg_boundaries(segment+1);
end_point = seg_boundaries(segment+2);
step = (end_point - start)/16;
position = floor((abs_x - start)/step);
% 组合成 8bit 码字
pcm_code = [sign_bit, dec2bin(segment,3)-'0', dec2bin(position,4)-'0'];
end
性能验证
测试不同幅度正弦波的量化效果:
% 生成测试信号
fs = 8000; t = 0:1/fs:1;
small_signal = 0.01*sin(2*pi*440*t);
large_signal = 0.9*sin(2*pi*440*t);
% 编码解码
small_decoded = a_law_decoder(a_law_encoder(small_signal));
large_decoded = a_law_decoder(a_law_encoder(large_signal));
% 计算 SNR
snr_small = 10*log10(var(small_signal)/var(small_signal-small_decoded));
典型结果:
– 小信号 (0.01V):SNR≈35dB
– 大信号 (0.9V):SNR≈38dB
新手避坑指南
- 归一化陷阱 :
- 未归一化会导致段判断错误
-
建议先做限幅处理
-
段边界跳变 :
% 错误示范:直接比较边界值 if x > 1/64 % 可能漏判临界点 % 正确做法:if x >= 1/64 - eps % 考虑浮点误差 -
解码同步 :
- 实际系统中建议添加帧同步头
- 可加入奇偶校验位
进阶思考方向
- 动态调整 A 值适应不同信源
- 与 DPCM 结合减少冗余
- 用 CORDIC 算法优化硬件实现
通过这次实践,我深刻体会到通信算法中工程折衷的艺术。13 折线看似粗糙,但在复杂度和性能间取得了完美平衡。建议读者尝试修改段数(比如 15 折线),亲自感受量化阶跃的变化规律。
正文完
