数据压缩实验六 MPEG音频编码实验
程序员文章站
2022-03-12 20:07:58
一、实验原理1、感知编码的基本思路(1)心理声学模型:听觉系统中存在一个听觉阈值电平,低于这个电平的声音信号就听不到。听觉阈值的大小随声音频率的改变而改变。一个人是否听到声音取决于声音的频率,以及声音的幅度是否高于这种频率下的听觉阈值。听觉掩蔽特性:即听觉阈值电平是自适应的,会随听到的不同频率声音而发生变化。声音压缩算法可以确立这种特性的模型来取消更多的...
一、实验原理
1、感知编码的基本思路
(1)心理声学模型:
听觉系统中存在一个听觉阈值电平,低于这个电平的声音信号就听不到。
听觉系统中存在一个听觉阈值电平,低于这个电平的声音信号就听不到。
- 听觉阈值的大小随声音频率的改变而改变。
- 一个人是否听到声音取决于声音的频率,以及声音的幅度是否高于这种频率下的听觉阈值。
声音压缩算法可以确立这种特性的模型来取消更多的冗余数据。
(2)人耳听觉特性
人类听觉系统大致等效于一个在0Hz到20KHz频率范围内由25个重叠的带通滤波器组成的滤波器组。
- 人耳不能区分同一频带内同时发生的不同声音;
- 人耳频带被称为临界频带(critical band);
临界频带是心理声学模型分析的基本单位。
掩蔽效应在一定频率范围内不随带宽增大而改变,直至超过某个频率值。
2.MPEG音频压缩编码
“两条线”和时频分析的矛盾:
- 通过子带分析滤波器组使信号具有高的时间分辨率,确保在短暂冲击信号情况下,编码的声音信号具有足够高的质量又可以使信号通过FFT运算具有高的频率分辨率,因为掩蔽阈值是从功率谱密度推出来的。
- 输入声音信号经过一个多相滤波器组,变换到多个子带。同时经过“心理声学模型”计算以频率为自变量的噪声掩蔽阈值。量化和编码部分用信掩比SMR决定分配给子带信号的量化位数,使量化噪声<掩蔽域值。最后通过数据帧包装将量化的子带样本和其它数据按照规定的帧格式组装成比特数据流。
编码器说明:
(1)多相滤波器组,用来分割子带
(2)量化和编码
- 比例因子的取值和编码
对各个子带每12个样点进行一次比例因子计算。先定出12个样点中绝对值的最大值。查比例因子表中比这个最大值大的最小值作为比例因子。用6比特表示。
- 比特分配及编码
比特分配的过程:
- 对每个子带计算掩蔽-噪声比MNR,是信噪比SNR –信掩比SMR,即:MNR = SNR –SMR
- 使整个一帧和每个子带的总噪声-掩蔽比最小。这是一个循环过程,每一次循环使获益最大的子带的量化级别增加一级,当然所用比特数不能超过一帧所能提供的最大数目。
- 子带样值的量化和编码
输入以12个样本为一组,每组样本经过时间-频率变换之后进行一次比特分配并记录一个比例因子(scale factor)。
比特分配信息告诉解码器每个样本由几位表示,比例因子用6比特表示,解码器使用这个6比特的比例因子乘逆量化器的每个输出样本值,以恢复被量化的子带值。比例因子的作用是充分利用量化器的量化范围,通过比特分配和比例因子相配合,可以表示动态范围超过120dB的样本。
比特分配信息告诉解码器每个样本由几位表示,比例因子用6比特表示,解码器使用这个6比特的比例因子乘逆量化器的每个输出样本值,以恢复被量化的子带值。比例因子的作用是充分利用量化器的量化范围,通过比特分配和比例因子相配合,可以表示动态范围超过120dB的样本。
(3)数据帧包装
二、实验流程分析
1、理解程序设计的整体框架
2、理解感知音频编码的设计思想
- 两条线
- 时-频分析的矛盾!
- 临界频带的概念
- 掩蔽值计算的思路
5、输出音频的采样率和目标码率
6、选择某个数据帧,输出
- 该帧所分配的比特数
- 该帧的比例因子
- 该帧的比特分配结果
三、关键代码及分析
在m2aenc.c中添加代码:
FILE *output=NULL;
output=fopen("output.txt","w");
……
//////add by zgy
if(frameNum==100)
{
int k,t,i;
fprintf(output,"sample_rate=%.1f khz\n",s_freq[header.version][header.sampling_frequency]);///输出采样率
fprintf(output,"bitrate=%d kbps\n", bitrate[header.version][header.bitrate_index]);///输出目标码率
fprintf(output,"frameNum=%d\n",frameNum);
fprintf(output,"available_bits=%d\n",adb);///输出该帧的可用比特数
fprintf(output,"scale_factors:\n");///输出该帧的比例因子
for(k=0;k<nch;k++)
{
fprintf(output,"channel[%d]\n",k);
for(i=0;i<frame.sblimit;i++)
{
fprintf(output,"subband[%d]:",i);
for(t=0;t<3;t++)
{
fprintf(output,"%d\t",scalar[k][t][i]);
}
fprintf(output,"\n");
}
}
}
///end
transmission_pattern (scalar, scfsi, &frame);
main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts);
///add by zgy
if(frameNum==100)
{
int k,i;
fprintf(output,"bit_allocation:\n");///输出该帧的比特分配结果
for(k=0;k<nch;k++)
{
fprintf(output,"channel[%d]\n",k);
for(i=0;i<frame.sblimit;i++)
{
fprintf(output,"subband[%d]:%d\n",i,bit_alloc[k][i]);
}
}
}
///end
四、实验结果分析
从输出结果可以看到,这是一个单声道音频文件,每个子带的三个比例因子相差不大,通过采用比例因子选择信息可以压缩更多的冗余数据;从比特分配结果可以看到,低频子带分配的比特数较多,高频分配的较少,这样可以保留更多的有用数据,使压缩后的音频失真最小。
本文地址:https://blog.csdn.net/zgyggy/article/details/74097167