MPEG(Moving Picture Experts Group,动态图像专家组)是ISO(International Standardization Organization,国际标准化组织)与IEC(International Electrotechnical Commission,国际电工委员会)于1988年成立的专门针对运动图像和语音压缩制定国际标准的组织。
MPEG标准主要有以下五个,MPEG-1、MPEG-2、MPEG-4、MPEG-7及MPEG-21等。该专家组建于1988年,专门负责为CD建立视频和音频标准,而成员都是为视频、音频及系统领域的技术专家。及后,他们成功将声音和影像的记录脱离了传统的模拟方式,建立了ISO/IEC11172压缩编码标准,并制定出MPEG-格式,令视听传播方面进入了数码化时代。因此,大家现时泛指的MPEG-X版本,就是由ISO (InternationalOrganization for Standardization) 所制定而发布的视频、音频、数据的压缩标准。
MPEG标准的视频压缩编码技术主要利用了具有运动补偿的帧间压缩编码技术以减小时间冗余度,利用DCT技术以减小图像的空间冗余度,利用熵编码则在信息表示方面减小了统计冗余度。这几种技术的综合运用,大大增强了压缩性能。
感知音频编码
原理框架
输入声音信号经过一个多相滤波器组,变换到多个子带。同时,经过“心理声学模型”计算以频率为自变量的噪声掩蔽阈值、量化和编码部分用信掩比SMR决定分配给子带信号的量化位数,使量化噪声<掩蔽阈值。最后通过数据帧包装将量化的子带样本和其他数据按照规定的帧格式组装成比特数据流。
MPEG音频压缩编码框架主体分为两条线:
- 红框部分:PCM码流经多相滤波器组变换为32个子带的频域信号。以1152个样本为单位,输入到滤波器组中进行32个子带的分解,即以32个样本为一个时间窗口,做36次自带分解,形成36个样本,形成以12个样本为单位的3个块,以此进行比例因子的提取和选择,通过频域分析线路的辅助,进行后续的量化等工作。

- 蓝框部分:对PCM信号进行FFT,和比例因子共同输入到心理声学模型中,输出SMR并生成听阈曲线,再结合码率限制进行动态比特分配,使整帧和每个子带的总噪声-掩蔽比最小,最终将量化后的子带样本和边信息编码数据以及辅助数据按照规定的帧格式组装成帧比特流输出。
分成上下两条线进行压缩编码,是因为时-频之间存在矛盾。
MPEG音频压缩编码的第一条线,利用子带分析滤波器组使信号具有高的时间分辨率,确保在短暂冲击信号情况下,编码的声音信号仍具有足够高的质量,但不能精确地反映人耳的听觉特性。单独遵循第二条线进行FFT运算,其只能说明哪些频率成分存在,不能说明这些频率成分在什么时间出现,二者结合可以使信号具有高的频率分辨率,因为掩蔽阈值是从功率谱密度推出来。
心理声学模型
人耳听觉系统
人耳听觉系统大致等效于一个信号通过一组并联的不同中心频率的带通滤波器。中心频率与信号频率相同的滤波器具有最大响应,中心频率偏离信号频率较多的滤波器不会产生响应。在0Hz到20kHz频率范围内由25个重叠的带通滤波器组成滤波器组。
听者在噪声中听某一纯音时,只启用中心频率与信号频率相同的那个听觉滤波器,而噪声信号只有通带范围内的部分信号能通过,其余频率成分被抑制。
临界频带
临界频带是指当某个纯音被以它为中心频率、且具有一定带宽的连续噪声所掩蔽时,如果该纯音刚好被听到时的功率等于这一频带内的噪声功率,这个带宽为临界频带宽度。 通常认为从20Hz到16kHz有25个临界频带,单位为bark,1 Bark = 一个临界频带的宽度。
在低频子带中,为了保护音调和共振峰的结构,就要求用较小的量化阶、较多的量化级数,即分配较多的位数来表示样本值。而话音中的摩擦音和类似噪声的声音,通常出现在高频子带中,对它分配较少的位数。具体如何分配,则是要参考码率和心理声学模型。
掩蔽值计算
1.将样本变换到频域
32个等分的子带信号并不能精确地反映人耳的听觉特性。于是引入FFT补偿频率分辨率不足的问题。采用Hann加权和DFT,因为模型需要更精细的频率分辨率,而且计算掩蔽阈值也需要每个频率的幅值。
- layerⅠ:采用512个样本窗口,layerⅡⅢ:1024个样本窗口。
- layerⅠ:每帧384个样本点,512个样本点足够覆盖。
- layerⅡ:每帧1152个样本点,每帧两次计算,选择两个信号掩蔽比(SMR)中较小的一个。
2.确定声压级别
子带n中的声压级别
其中X(k)是在子带n中的频谱线的声压级别,是在一帧中子带n的三个缩放因子中最大的一个。
3.考虑安静时阈值
也即绝对阈值,有根据输入PCM采样率编制的“频率,临界频带率和绝对阈值”表,由多位科学家经多次心理声学实验所得。

4.将音频信号分解为“乐音”和“非乐音/噪声”部分
根据音频频谱的局部功率最大值确定乐音成分,局部峰值为乐音,然后将本临界频带内的剩余频谱合在一起,组成一个代表噪声频率(无调成份)。
5.音调和非音调掩蔽成分的消除
利用标准中给出的绝对阈值消除被掩蔽成分;考虑在每个临界频带内,小于0.5Bark的距离中只保留最高功率的成分。
6.单个掩蔽阈值的计算
音调成分和非音调成分单个掩蔽阈值根据标准中给出的算法求得。
而某一频率点的总掩蔽阈值,可通过该点的绝对掩蔽阈值与单独掩蔽阈值相加获得。第一项为绝对阈值、第二项为乐音掩蔽、第三项为噪音掩蔽。


8.每个子带的掩蔽阈值
选择出本子带中最小的阈值作为子带阈值
9.计算每个子带信号掩蔽比SMR
SMR=信号能量/掩蔽阈值,将SMR传递给编码单元。
码率分配
MPEG-1声音压缩编码是国际上第一个高保真声音数据压缩的国际标准,它分为三个层次:
--层1(Layer 1):编码简单,用于数字盒式录音磁带
layer Ⅰ
在调整到固定的码率之前,要先确定可用于样值编码的有效比特数,这个数值取决于比例因子、比例因子选择信息、比特分配信息以及辅助数据所需比特数。
目标是使整帧和每个子带的总噪声-掩蔽比最小。
比特分配的过程:
计算噪声-掩蔽比NMR=信掩比SMR-信噪比SNR
- 其中SNR由MPEG-1标准给定,NMR表示波形误差与感知测量之间的误差
- 比特分配时的最好情况:信噪比=信掩比
码率分配的实现思路:
- 初始还未分配bit时,信噪比为0,噪掩比等于信掩比。
- 根据(目标)码率计算预估比特数
- 优先对噪掩比高的子带分配比特(如果噪掩比是负数则不考虑),使获益最大的子带的量化级别增加一级
- 量化比特数每增加1bit,信噪比会上升6db,噪掩比会下降6db
- 分配比特后重新计算该子带的噪掩比,之后重复上述过程,直到没有比特可用或每个子带的噪掩比都为0


在听阈曲线之下的不分配比特,掩蔽域之下的部分不分配比特。

layer Ⅱ
- 每帧包含1152个样本。低、中、高频段对比特分配不同,分别用4、3、2比特。比特流中增加了一个比特因子选择信息域,解码器根据这个域的信息可知道是否需要以及如何共享比例因子
- 采用线性子带划分
- 使用频域掩蔽和时域掩蔽特性
- SMR使用全局掩蔽阈值
- 采用心理声学模型Ⅰ
layer Ⅲ
- 每帧数据包含1152个样本(32x12x3)
- 采用临界频带划分子带
- 使用频域掩蔽和时域掩蔽特性,还考虑立体声冗余特性
- 第3层使用的滤波器组是多相/MDCT混合滤波器组,并且使用了心理声学模型2来评估掩蔽门限,除了考虑使用频域掩蔽特性和时间掩蔽特性之外,还考虑了立体声数据的冗余。
- 为了增加编码增益,采用了非均匀量化和Huffman编码,并且使用了称为比特池的缓存技术来维持编码效率和使量化噪声保持在掩蔽门限以下。
- 采用心理声学模型Ⅱ
程序框架
1.音频输入,对滑动窗口中的数据进行滤波,以获得每个通道的32个子带。
// 读取音频长度
unsigned long get_audio (FILE * musicin, short buffer[2][1152], unsigned long num_samples, int nch, frame_header *header)
// 将音频存入buffer
unsigned long read_samples (FILE * musicin, short sample_buffer[2304], unsigned long num_samples, unsigned long frame_size)
// 计算可用比特数,即比特预算
int available_bits (frame_header *header, options * glopts);
// 对buffer中存储的音频数据进行子带分解和滤波
void WindowFilterSubband( short *pBuffer, int ch, double s[SBLIMIT] );
2.计算比例因子,及其选择信息。
// 二分法查找比例因子
void scale_factor_calc (double[][3][SCALE_BLOCK][SBLIMIT], unsigned int[][3][SBLIMIT], int, int);
// 每个子带对应的三组样本(每组12个样本)分别选择三个不同的比例因子
void pick_scale (unsigned int[2][3][SBLIMIT], frame_info *, double[2][SBLIMIT]);
// 比例因子选择信息
void transmission_pattern (unsigned int[2][3][SBLIMIT], unsigned int[2][SBLIMIT], frame_info *);
3.选定的心理声学模型,计算频域掩蔽电平。
//两种心理声学模型
void psycho_1 (short buffer[2][1152], double scale[2][SBLIMIT],
double ltmin[2][SBLIMIT], frame_info * frame)
void psycho_2 (short int *buffer, short int savebuf[1056], int chn,
double *smr, double sfreq, options *glopts)
4.动态比特分配,可添加冗余校验
// 计算MNR,循环进行动态比特分配
void main_bit_allocation_new (double SMR[2][SBLIMIT],
unsigned int scfsi[2][SBLIMIT],
unsigned int bit_alloc[2][SBLIMIT], int *adb,
frame_info * frame, options * glopts);
//选择是否进行冗余校验
void CRC_calc (frame_info * frame, unsigned int bit_alloc[2][SBLIMIT],
unsigned int scfsi[2][SBLIMIT], unsigned int *crc)
5.将比特分配,比例因子以及相关信息打包至比特流。
// 比特分配
void encode_bit_alloc (unsigned int[2][SBLIMIT], frame_info *,
Bit_stream_struc *);
// 比例因子
void encode_scale (unsigned int[2][SBLIMIT],
unsigned int[2][SBLIMIT],
unsigned int[2][3][SBLIMIT], frame_info *,
Bit_stream_struc *);
// 比例因子选择信息
void transmission_pattern (unsigned int scalar[2][3][SBLIMIT],
unsigned int scfsi[2][SBLIMIT],
frame_info * frame)
6.对子带进行量化,并进行打包成比特流。
// 子带量化
void subband_quantization (unsigned int[2][3][SBLIMIT],
double[2][3][SCALE_BLOCK][SBLIMIT],
unsigned int[3][SBLIMIT],
double[3][SCALE_BLOCK][SBLIMIT],
unsigned int[2][SBLIMIT],
unsigned int[2][3][SCALE_BLOCK][SBLIMIT],
frame_info *);
// 量化后编码
void sample_encoding (unsigned int[2][3][SCALE_BLOCK][SBLIMIT],
unsigned int[2][SBLIMIT], frame_info *,
音频测试
输出音频的采样率和目标码率,以test.wav为例

输入音频采样率为44.1kHz,输出比特率为192kbps。
选择三个不同特性的音频文件,针对某个数据帧,输出该帧所分配的比特数、比例因子和比特分配结果
- 噪声(持续噪声、突发噪声):持续风扇噪声noise1.wav,突发撞击噪声noise2.wav;
- 音乐:截取十秒纯音乐作为乐音输入music.wav;
- 音乐+噪声:将上述三者合并作为测试音频mix.wav。
代码修改
common.h 中加入定义
#define FRAME_TRACE 1
FILE* output;
int gr = 0;
m2aenc 中加入trace输出
#if FRAME_TRACE
output = fopen("output.txt", "a");
if (frameNum == 7) {
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 (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
print_config 中加入如下输出
#if FRAME_TRACE
printf("-------------调试信息-------------\n");
printf("输入文件:%s\n", inPath);
printf("输出文件:%s\n", outPath);
printf("采样频率:%.1f kHz\n", s_freq[header->version][header->sampling_frequency]);
printf("目标码率:%d kbps\n", bitrate[header->version][header->bitrate_index]);
#endif // FRAME_TRACE
输出结果
| noise1 | ![]() | ![]() |
| noise2 | ![]() | ![]() |
| music | ![]() | ![]() |
| mix | ![]() | ![]() |
MPEG音频编码利用多相滤波器组、心理声学模型和码率分配技术,结合人耳听觉特性进行高效压缩。心理声学模型包括临界频带、掩蔽值计算,通过计算噪声掩蔽阈值进行动态比特分配,适用于不同应用场景,如MP3音乐压缩。MPEG音频分为Layer Ⅰ、Ⅱ、Ⅲ,层3(MP3)编码复杂,适合互联网高质量声音传输。









3052

被折叠的 条评论
为什么被折叠?



