目录
MPEG编码思想
整体概述
(1)基本思想
分析信号,去掉不能被感知的部分
(2)MPEG-1声音的主要性能
输入为PCM信号,采样率为32,44.1或48kHz,输出为32kbps到384kbps。
(3)三个独立的压缩层次
Layer1:编码器最简单,384kbps(4:1, 用于小型数字盒带DCC,Compact Cassette)
Layer2:编码器复杂程度中等,256kbps~192kbps(6: 1~8:1, 用于DAB、CD-I和VCD)
Layer3:编码器最为复杂,64kbps,用于ISDN,网络 音频。
多相滤波器组(Polyphase Filter Bank)
原理
分割子带。将PCM样本变换到32个子带的频域信号。
如果输入的采样频率为48kHz,那么子带的频率宽度为48/(2*32)=0.75Hz
缺点
等带宽的滤波器组与人类听觉系统的临界频带不对应
在低频区域,单个子带会覆盖多个临界频带。在这种情况下,量化比特数不能兼每个临界频带
滤波器组与其逆过程不是无失真的
但滤波器组引入的误差差很小,且听不到
子带间频率有混叠
滤波后的相邻子带有频率混叠现象,一个子带中的信号可以影响相邻子带的输出
与临界频带比较
心里声学模型I
心理声学模型Ⅰ
计算信号中不可听觉感知的部分,计算噪声遮蔽效应
MPEG-I 标准定义了两个模型
心理声学模型1
计算复杂度低,但对假设用户听不到的部分压缩太严重
心理声学模型2
提供了适合Layer III编码的更多特征
实际实现的模型复杂度取决所需要的压缩因子,如大的压缩因子不重要,则可以完全不用心理声学模型。此时位分配算法不使用SMR( Signal Mask Ratio ),而是使用SNR
1.将样本变换到频域
32个等分的子带信号不能精确地反映人耳的听觉特性,所以我们引入FFT补偿频率分辨率不足的问题。
采用Hann加权和DFT
Hann加权减少频率中的边界效应。
此变换不同于多相滤波器组,因为模型需要更精细的频率分辨率,而且计算掩蔽阈值也需要每个频率的幅值。
模型1:采用512(Layer Ⅰ)或者1024(Layer Ⅱ and Ⅲ)样本窗口:
Layer Ⅰ:每帧384个样本点,512个样本点足够覆盖。
Layer Ⅱ and Ⅲ:每帧1152个样本点,每帧两次计算,模型1选择两个信号掩蔽比(SMR)中较小的一个。
2.确定声压级别
3.考虑安静时阈值,也即绝对阈值
也即绝对阈值。在标准中有根据输入PCM信号的采样率编制的“频率、临界频带率和绝对阈值”表。此表为多位科学家经多次心理声学实验所得。
4.将音频信号分解成“乐音(Polyphase Filter Bank)tones)” 和“非乐音/噪声。
模型1:根据音频频谱的局部功率最大值确定乐音成分。局部峰值为乐音,然后将本临界频带内的剩余频谱合在一起,组成一个代 表噪声频率(无调成份)。
要列出谱线 X ( k ) X(k) X(k)的有调和无调,需执行下面的三个步骤:
标明局部最大;如果 X ( k ) X(k) X(k)比相邻的两个谱线都大,则 X ( k ) X(k) X(k)为局部最大值。
列出有调成分,计算声压值。如果 X ( k ) − X ( k + j ) ≥ 7 d B X(k)-X(k+j) \ge 7dB X(k)−X(k+j)≥7dB,则 X ( k ) X(k) X(k)为有调成分。j随谱线的位置不同而不同。
列出无调成分,计算功率。在每个临界频带内将所有余留谱线的功率加起来形成临界频带内无调成分的声压级。并列出以下参数:最接近临界频带几何平均值的谱线标记k,声压级以及无调指示。
5.音调和非音调掩蔽成分的消除
利用标准中给出的绝对阈值消除被掩蔽成分;考虑在每个临界频带内,小于0.5Bark的距离中只保留最高功率的成分。
6.单个掩蔽阈值的计算
音调成分和非音调成分单个掩蔽阈值根据标准中给出的算法求得。
7.全局掩蔽阈值的计算
要考虑别的临界频带的影响。一个掩蔽信号会对其它频带上的信号产生掩蔽效应。这种掩蔽效应称为掩蔽扩散。
8.每个子带的掩蔽阈值
选择出本子带中最小的阈值作为子带阈值。
9.计算每个子带信号掩蔽比(signal-to-mask ratio, SMR),将SMR传递给编码单元
SMR = 信号能量 / 掩蔽阈值。
LayerI编码
码率分配
在调整到固定的码率之前:先确定可以用于样值编码的有效比特数,这个数值取决于比例因子、比例因子选择信息、比特分配信息和辅助数据所需bit数。
比特分配过程: 对每个子带计算掩蔽-噪声比MNR,是信噪比-信掩比,即 MNR=SNR−SMR。
算法:使整帧和每一个子带的总噪声-掩蔽比NMR最小。
计算NMR:NMR=SMR−SNR。
其中SNR 由MPEG-I标准给定 (为量化水平的函数)
NMR:表示波形误差与感知测量之间的误差
其中SNR 由MPEG-I标准给定 (为量化水平的函数)
NMR:表示波形误差与感知测量之间的误差
对最高NMR的子带分配比特,使获益最大的子带的量化级别增加一级
重新计算分配了更多比特子带的NMR
装帧
帧头格式
LayerII编码
概述
与Layer I类似,但对Layer I有增强
装帧、缩放因子表示、量化
缩放因子(比例因子)一般从低频子带到高频子带出现连续下降
帧:
3 组/帧 x 12个样本/子带 x 32个子带/帧 = 1152个样本/帧
每个样本的overhead更少
缩放因子:每个子带的3个组尽可能共用缩放因子
Layer I: 1个/12个样本
Layer II: 1个/(24/36)个样本
1/2/3个缩放因子和缩放因子选择信息(scale factor selection information, SCFSI) (每子带2比特)一起传送
如果缩放因子和下一个只有很小的差别,就只传送大的一个,这种情况对于稳态信号经常出现
如果要给瞬态信号编码,则要在瞬态的前、后沿传送两个或所有三个比例因子
量化
Layer I:每个子带从相同的量化集合中选择
每个子带取共14个量化器中的一个
Layer II:
根据采样和码率量化,不同子带可以从不同的量化器集合中选择
某些(高频)子带的比特数可能为0
对量化级别在3、5、9级时,采用“颗粒” 优化
颗粒= 3 个样本,根据颗粒选择量化水平
例:3个样本 @ 3个量化水平 = 27种可能的值 5 比特
不采用颗粒量化:1个样本 @ 3个量化水平 = 2比特 x 3 个样本 6 比特
装帧
实验内容
- 输出音频的采样率和目标码率
- 选择三个不同特性的音频文件
- 噪声(持续噪声、突发噪声)
- 音乐
- 混合
- 某个数据帧,输出
- 该帧所分配的比特数
- 该帧的比例因子
- 该帧的比特分配结果
实验代码
定义宏
在common.h中添加
#define FRAME_TRACE 1
进行音频信息打印
在 m2aenc.h的main函数的while()中添加
#if FRAME_TRACE
FILE* output;
output = fopen("output.txt", "a");
if (frameNum == 10) {
fprintf(output, "声道数:%d\n", nch);
fprintf(output, "目前观测第 %d 帧\n", frameNum);
fprintf(output, "本帧比特预算:%d bits\n", adb);
fprintf(output, "\n");
fprintf(output, "========== 比例因子 ==========\n");
for (ch = 0; ch < nch; ch++) // 每个声道单独输出
{
fprintf(output, "------ 声道%2d ------\n", ch + 1);
for (sb = 0; sb < frame.sblimit; sb++) // 每个子带
{
fprintf(output, "子带[%2d]:\t", sb + 1);
for (int gr = 0; gr < 3; gr++) {
fprintf(output, "%2d\t", scalar[ch][gr][sb]);
}
fprintf(output, "\n");
}
}
fprintf(output, "\n");
fprintf(output, "========== 比特分配表 ==========\n"); //输出比特分配结果
for (ch = 0; ch < nch; ch++) {
fprintf(output, "------ 声道%2d ------\n", ch + 1); //按声道分配
for (sb = 0; sb < frame.sblimit; sb++) {
fprintf(output, "子带[%2d]:\t%2d\n", sb + 1, bit_alloc[ch][sb]);
}
fprintf(output, "\n");
}
}
fclose(output);
#endif // FRAME_TRACE
实验结果
噪声
音乐
![]() | ![]() |
持续噪声
![]() | ![]() |
混合音频
将刚才的音乐与噪声混合
![]() | ![]() |